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方法处理任意多个可迭代对象。它从每个可迭代对象中取出当前值,作为指定函数的参数。