【问题标题】:Using map with multiple args使用带有多个参数的地图
【发布时间】:2013-12-17 23:45:07
【问题描述】:

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

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

【问题讨论】:

  • Guido 实际上对map 有强烈的反感,并且确实计划将其从python 3 中删除。然而,由于流行的观点,他没有。 artima.com/weblogs/viewpost.jsp?thread=98196
  • lambdas 限制太多太慢是 Python 的错。否则map 在列表理解变得更难阅读的某些情况下会很有用。
  • map 早于理解。
  • @MihaiMaruseac lambdas 没用。如果您想使用多个表达式,只需使用 def 并定义一个真正的函数。拥有更大的lambdas 将完全不可读。其他语言需要lambda 表达式,因为它们不能定义内部函数,但python 确实 有它们,所以lambdas 只有在你需要一个简单的时候才有用-expr 函数作为参数。

标签: python dictionary functional-programming


【解决方案1】:

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

类似于map(),但在最短的迭代用完时停止 而不是填写 None 以获得更短的迭代。 原因 不同之处在于无限迭代器参数通常是 map() 的错误(因为输出已被完全评估)但是 代表提供论据的一种常见且有用的方式 imap().

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

python3 最显着的变化之一是许多内置函数现在返回生成器而不是lists,包括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

【讨论】:

  • 哇,我想我是 python 的相对新手,因为我什至无法想象没有理解的语言。它们似乎是语言中如此强大且不可或缺的一部分,以至于 python
  • @wim 是的,它们是较新 python 版本的“杀手级功能”之一。 Python 完全 不同的语言。特别是python string模块充满了splitstrip等函数)。在过去的 10 到 15 年里,该语言改进了很多。
猜你喜欢
  • 2014-10-03
  • 2014-05-23
  • 1970-01-01
  • 2018-10-07
  • 2017-11-14
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多