Python map()函数应用于集合,标量函数将数值从定义域映射到值域。例如math.sqrt()
函数,它将浮点数x
映射为另一浮点数y = sqrt(x)
,并且满足 y^2 = x,定义域是所有正实数。这里的映射关系可以通过计算或者插值查表完成。
map()
函数的作用与之类似:它将一个集合映射为另一个集合,保证将输入集合中的每个元素从定义域映射到值域中。这是使用内置函数处理集合的一种理想方式。
第一个例子是解析一段文本,获取一系列数值。假设现有如下文本段:
>>> text= """\
... 2 3 5 7 11 13 17 19 23 29
... 31 37 41 43 47 53 59 61 67 71
... 73 79 83 89 97 101 103 107 109 113
... 127 131 137 139 149 151 157 163 167 173
... 179 181 191 193 197 199 211 223 227 229
... """
用以下生成器函数重组这段文本:
>>> data = list(
... v for line in text.splitlines()
... for v in line.split())
首先把文本按行拆分,再对每一行使用空格进行二次拆分,结果如下所示:
['2', '3', '5', '7', '11', '13', '17', '19', '23', '29',
'31', '37', '41', '43', '47', '53', '59', '61', '67', '71',
'73', '79', '83', '89', '97', '101', '103', '107', '109', '113',
'127', '131', '137', '139', '149', '151', '157', '163', '167',
'173', '179', '181', '191', '193', '197', '199', '211', '223',
'227', '229']
现在需要对序列中每个字符串元素使用int()
函数,可以借助map()
函数来实现,如下所示:
>>> list(map(int, data))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,
61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131,
137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197,
199, 211, 223, 227, 229]
map()
函数把int()
函数应用于序列的每个元素,返回结果是数值列表,而不是字符串列表。
map()
函数的返回结果是可迭代对象,它能处理任何类型的可迭代对象。
可以通过map()
函数将任何Python函数应用于集合。很多内置函数可以应用于这样的“映射-处理”场景中。
在map()
中使用匿名函数
假设现在需要把旅行数据中的距离从海里转换为英里,也就是给每个路径段的距离字段乘以6076.12 / 5280
,即1.150780
。
可以使用map()
函数完成计算:
map(
lambda x: (start(x), end(x), dist(x) * 6076.12 / 5280),
trip
)
map()
函数将作为参数的匿名函数应用于旅行数据的每个路径段,该匿名函数又会使用其他匿名函数分离路径段中的起点、终点和距离字段,最终计算出以英里为单位的距离值,然后重新组合成包含起点、终点和英里距离的元组。
此过程与下面的生成器表达式完全一致:
((start(x), end(x), dist(x) * 6076.12 / 5280) for x in trip)
这样就用生成器表达式完成了相同的处理。
二者的重要区别是:map()
函数可以复用已有的函数定义或者匿名函数,更好的方法如下所示:
to_miles = lambda x: start(x), end(x), dist(x) * 6076.12 / 5280
trip_m = map(to_miles, trip)
这种实现方式将变换逻辑to_miles
从对数据的处理过程中分离了出来。