map() 是否像“for”一样迭代列表?使用 map 与 for 是否有价值?

如果是这样,现在我的代码如下所示:

for item in items:
    item.my_func()

如果有意义的话,我想把它做成map()。那可能吗?一个例子是什么样的?

有帮助吗?

解决方案

你可以使用 map 而不是 for 您已经展示了循环,但由于您似乎没有使用 item.my_func(), , 这是 不建议. map 如果您想对列表的所有元素应用没有副作用的函数,则应使用。在所有其他情况下,请使用显式 for 循环。

另外,从 Python 3.0 开始 map 返回一个生成器,所以在这种情况下 map 不会表现相同(除非您明确评估生成器返回的所有元素,例如通过致电 list 在上面)。


编辑: 吉比布 在评论中要求澄清原因 map的第一个参数不应该是有副作用的函数。我会尝试回答这个问题:

map 旨在传递一个函数 f 在数学意义上. 。在这种情况下,按什么顺序并不重要 f 应用于第二个参数的元素(只要它们是 当然,按照原来的顺序)。更重要的是,在这种情况下 map(g, map(f, l)) 在语义上等价于 map(lambda x: g(f(x)), l), 无论顺序如何 fg 应用于各自的输入.

例如,是否并不重要 map 立即返回迭代器或完整列表。然而,如果 f 和/或 g 引起副作用,那么只有当语义 map(g, map(f, l)) 使得在任何阶段 g 应用于第一个 n 返回的元素 map(f, l)map(f, l) 适用 f(n+1)​的第一个元素 l. 。(意思是 map 必须执行尽可能最懒的迭代——Python 3 中是这样做的,但 Python 2 中不是!)

更进一步:即使我们假设 Python 3 实现 map, ,如果输出 map(f, l) 例如通过传递 itertools.tee 在供应给外部之前 map 称呼。

上述讨论可能看起来是理论上的,但随着程序变得越来越复杂,它们变得更难以推理,因此更难调试。确保某些事情不变可以在一定程度上缓解该问题,并且实际上可以防止一整类错误。

最后, map 让许多人想起了各种(纯)函数式语言中真正的函数式对应物。向它传递一个带有副作用的“函数”会让那些人感到困惑。因此,将其视为替代方案(即使用显式循环)并不比调用更难实现 map, ,强烈建议限制使用 map 适用于要应用的功能不会引起副作用的情况。

其他提示

可以写此使用图像这样:

map(cls.my_func, items)

与类你迭代的物品的替换CLS。

正如Stephan202提到的,这是的不推荐在这种情况下。

作为一个规则,如果你想在应用列表中的一些功能,每一个项目建立一个新的列表,使用地图。这暗示这意味着函数没有副作用,因此你可以(可能)并行运行地图。

如果你不希望创建一个新的列表,或者如果函数有副作用,使用for循环。这是在你的例子的情况。

有一个轻微的语义差异,这是在Python语言规范可能关闭。在地图的是明确并行,而的只有在特殊情况下。代码可以出从的,但仅与异常从逸出地图

在我看来的地图的不应该也保证功能应用,而的必须订购。据我所知没有Python实现是目前能够做到这一点的自动并行化。

如果您需要将您可以将您map一些很酷的螺纹或多核或分布式计算框架。 迪斯科是分布式的,对故障的erlang抗性和 - 基于蟒框架的一个例子。我将其配置于8芯的2盒现在我的程序运行感谢16倍的速度,向迪斯科簇,但是我不得不从列表解析重写我方案和循环映射/降低。

这是相同的协议,编写使用for循环和列表理解和地图/减少程序,但是当你需要它在集群上运行,你可以,如果你使用的map / reduce做到这一点几乎是免费的。如果你没有,那么,你将不得不改写。

请注意:如据我所知,蟒2.x的返回一个列表,而不是从图的迭代器。我听说这可以通过使用iter.imap()旁路(从未使用过它虽然)。

使用明确的for循环,当你不需要的结果列表后面(例如,有副作用的函数)。

使用列表理解,当你确实需要一个结果列表返回(返回直接基于输入值,例如函数)。

当你试图说服Lisp的用户Python是值得使用使用地图()。 ;)

map的主要优点是,当你想在一个列表中的每个元素上的一些计算的结果。例如,这个片段在列表中的每一个值加倍:

map(lambda x: x * 2, [1,2,3,4])  #=> [2, 4, 6, 8]

要注意的是map返回的结果一个新的名单是很重要的。它不会修改到位原始列表。

for同样的事情,你需要创建一个空的列表,并添加一个额外的行到for身体补充每个计算新名单的结果。所述map版本更加简洁和功能性。

地图有时可以比手动编码for循环更快的内置函数。尝试时序图(STR,范围(1000000))相对于一个类似的for循环。

map(lambda item: item.my_func(), items)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top