使用带有多个参数的地图

wim*_*wim 2 python dictionary functional-programming

Pythonmap可以采用多个可迭代对象,以便在可调用对象可以接受相同数量的输入参数时使用。如果输入可迭代对象的长度相同,则其行为类似于传递压缩参数的列表推导式,例如:

>>> iterables = 'spam', 'eggs'
>>> map(max, *iterables)
['s', 'p', 'g', 's']
>>> [max(*a) for a in zip(*iterables)]
['s', 'p', 'g', 's']
Run Code Online (Sandbox Code Playgroud)

当输入参数的长度不同时,它会变得很奇怪 - 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']
Run Code Online (Sandbox Code Playgroud)

为什么存在此功能,需要或有用的典型案例的示例是什么?我对函数式风格了解不多,我是否会错过map与多个参数相关的一些强大优势?3.x 中 API 更改的基本原理是什么?

Bak*_*riu 5

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

Like map()but 在最短的 iterable 耗尽时停止,而不是填充None较短的 iterable。差异的原因是无限迭代器参数通常是 的错误map()(因为输出已完全评估)但代表了向 提供参数的常见且有用的方式 imap()

截断使您可以轻松地执行类似操作map(func, itertools.repeat(5), [1,2,3])并迭代结果。旧的map那将是一个无限循环。

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

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

list(itertools.starmap(function, itertools.zip_longest(*iterables)))
Run Code Online (Sandbox Code Playgroud)

这可能有一些特殊情况的用法,但我从未见过它被使用过。可能大多数人甚至不知道它map接受一系列可迭代对象。因此,AFAIK 没有任何源自使用多个参数的超能力。

至于为什么map在语言中,那是因为map在列表理解之前很久就存在了。在列表理解之前,它对于构建列表非常有用。它不是为了向后兼容而删除的,因为很多人实际上喜欢它,尽管 Guido确实想删除它

要了解更多有关历史mapfilterreduce和其他功能方面,阅读:Python中的历史:Python的“功能性”特征的起源

  • @wim 是的,它们是较新 Python 版本的“杀手级功能”之一。Python <2.0 确实是一种*完全*不同的语言。尤其是python < 1.6,其中字符串没有方法(这就是为什么在python2中`string`模块充满了`split`、`strip`等函数)。在过去的 10 到 15 年里,语言已经*改进*了很多。 (2认同)