Python map()处理多个序列

Python map()函数处理多个序列,有时需要把多个序列放在一起处理。前面介绍过zip()函数可以将两个序列组合在一起,生成新的对序列(二元组序列)。很多时候需要对序列做如下处理:

map(function, zip(one_iterable, another_iterable))

首先基于两个可迭代序列创建新参数元组,在把一个函数应用于该元组,如下所示:

(function(x, y)
    for x, y in zip(one_iterable, another_iterable)
)

这里用生成器表达式代替了map()函数。

抽象前面的处理过程,如下所示:

def star_map(function, *iterables)
    return (function(*args) for args in zip(*iterables))

实际上,Python提供了一个更好的解决方案,我们不必运用上面的技术了。下面举例说明如何使用这个方法。

从XML文件中提取了一系列代表旅行路线的路径点信息,当时需要基于这一系列点数据创建包含起点和终点的路径段。

使用zip()函数处理可迭代对象的一个简化版本如下:

>>> waypoints = range(4)
>>> zip(waypoints, waypoints[1:])
<zip object at 0x101a38c20>
>>> list(_)
[(0, 1), (1, 2), (2, 3)]

这样就基于一维列表创建出了对序列,每个数据对包含相邻的两个点。较短的序列元素用完之后zip()函数的组合操作即结束。zip(x, x[1:])模式只能用于实例化的序列,以及由range()函数创建的可迭代对象。

创建数据对以便用haversine()函数计算路径上两点间的距离,其实现方法如下:

from ch02_ex3 import (lat_lon_kml, float_from_pair, haversine)

path = tuple(float_from_pair(lat_lon_kml()))
distances_1 = map(
    lambda s_e: (s_e[0], s_e[1], haversine(*s_e)),
    zip(path, path[1:])
)

首先把路径点信息加载到path变量中,实际上是一系列有序的经纬度数值对。由于下面要运用zip(path, path[1:])设计模式,所以变量只能是实例化的序列,不能是可迭代对象。
zip()函数的返回结果是包含起点、终点的二元组序列,而我们需要的是包括起点、终点和距离的三元组序列。这里的匿名函数从输入二元组中提取数据,计算出距离后组合生成三元组。

前面提过,可以用map()函数的高级形式将这一步简化为:

distances_2 = map(
    lambda s, e: (s, e, haversine(s, e)),
    path, path[1:])

请注意,map()函数的参数包括一个函数和两个可迭代对象。map()函数从两个可迭代对象中分别取出当前值,作为上面函数的输入参数。对于本例,这个指定的函数是一个返回包含起点、终点和距离的三元组的匿名函数。

map()函数的正式定义指出,它可以使用star-map方法处理任意多个可迭代对象。它从每个可迭代对象中取出当前值,作为指定函数的参数。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程