使用带有多个args的map

时间:2013-12-17 23:45:08

标签: python dictionary functional-programming

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变化的基本原理是什么?

1 个答案:

答案 0 :(得分:2)

关于为什么 map在python3中截断,这只是因为python3的map实际上是itertools.imap。文档说:

  

map()类似,但在最短的iterable耗尽时停止   而不是填充None更短的迭代。 原因   区别在于无限迭代器参数通常是一个   map()的错误(因为输出已完全评估)但是   表示提供参数的常用且有用的方法   imap()

截断允许您执行map(func, itertools.repeat(5), [1,2,3])之类的操作并迭代结果而不用担心。旧的map将是一个无限循环。

python3最重要的变化之一是许多内置函数现在返回生成器而不是list,包括mapzip。这种“增加的懒惰”改变了这些功能的使用方式,从而改变了行为。

至于为什么人们会使用python2的多次迭代来map我不知道。当然,这是(在python3中)的快捷方式:

list(itertools.starmap(function, itertools.zip_longest(*iterables)))

这可能有一些角落案例用法,但我从未见过它。 可能大多数人甚至不知道map接受一系列迭代。 因此,AFAIK没有任何来自使用多个参数的超能力。

至于为什么map在语言中,那是因为map早在列表推导之前就存在了。在列表推导之前,它对于构建列表非常有用。 它不是为了向后兼容而删除,因为很多人真的喜欢它, 虽然Guido did want to remove it

要详细了解mapfilterreduce的历史以及其他功能方面,请阅读:The History of Python: Origins of Python's "Functional" Features