Python的map
可以使用多个iterables,以便在callable可以接受相同数量的输入参数时使用。如果输入的iterables长度相同,那就像传递压缩参数的列表推导一样,例如:
>>> iterables = 'spam', 'eggs'
>>> map(max, *iterables)
['s', 'p', 'g', 's']
>>> [max(*a) for a in zip(*iterables)]
['s', 'p', 'g', 's']
当输入参数长度不同时,它会变得奇怪 - Python 2(docs)填充None
,但Python 3(docs)截断为最短迭代。
>>> map(max, 'spam', 'potato') # 2.x
['s', 'p', 't', 'm', 't', 'o']
>>> list(map(max, 'spam', 'potato')) # 3.x
['s', 'p', 't', 'm']
为什么这个功能存在,这是一个需要或有用的典型案例的例子?我对功能样式了解不多,我是否会错过map
与多个参数相关的强大优势? 3.x中API变化的基本原理是什么?
答案 0 :(得分:2)
关于为什么 map
在python3中截断,这只是因为python3的map
实际上是itertools.imap
。文档说:
与
map()
类似,但在最短的iterable耗尽时停止 而不是填充None
更短的迭代。 原因 区别在于无限迭代器参数通常是一个map()
的错误(因为输出已完全评估)但是 表示提供参数的常用且有用的方法imap()
强>
截断允许您执行map(func, itertools.repeat(5), [1,2,3])
之类的操作并迭代结果而不用担心。旧的map
将是一个无限循环。
python3最重要的变化之一是许多内置函数现在返回生成器而不是list
,包括map
和zip
。这种“增加的懒惰”改变了这些功能的使用方式,从而改变了行为。
至于为什么人们会使用python2的多次迭代来map
我不知道。当然,这是(在python3中)的快捷方式:
list(itertools.starmap(function, itertools.zip_longest(*iterables)))
这可能有一些角落案例用法,但我从未见过它。
可能大多数人甚至不知道map
接受一系列迭代。
因此,AFAIK没有任何来自使用多个参数的超能力。
至于为什么map
在语言中,那是因为map
早在列表推导之前就存在了。在列表推导之前,它对于构建列表非常有用。
它不是为了向后兼容而删除,因为很多人真的喜欢它,
虽然Guido did want to remove it。
要详细了解map
,filter
和reduce
的历史以及其他功能方面,请阅读:The History of Python: Origins of Python's "Functional" Features