在 Python 中,有两种方法可以将函数应用于可迭代对象的每个元素:
- 功能
map()
:
>>> lst = [1, 2, 3, 4]
>>> list(map(str, lst))
['1', '2', '3', '4']
>>> list(map(lambda a: a + 1, lst))
[2, 3, 4, 5]
- 列表包含:
>>> lst = [1, 2, 3, 4]
>>> [str(i) for i in lst]
['1', '2', '3', '4']
>>> [i + 1 for i in lst]
[2, 3, 4, 5]
《Python 之禅》中有这样一句话:
应该有一种——最好只有一种——明显的方法来做到这一点。
应该有一种,最好只有一种,明显的方法来做到这一点。
由于有两种方法可以将函数应用于可迭代对象,因此 Python 的创建者有充分的理由引入它们。
问题出现了:哪些?在上面的示例中,这两种方法看起来都很自然。显然,存在仅使用这些方法中的一种更容易的问题。那么什么时候最好使用map()
以及什么时候最好将其包含在列表中呢?
生成器(称为短迭代器)可以使用流条件。同时
map
不受外界条件影响。如果您只需要对每个元素应用一个函数(甚至是 lambda),请使用map
. 返回的对象可以迭代并转换为list
(如您的代码中所示)。当您需要生成并继续使用它时,生成器更适合,一个可迭代的对象,可能带有条件,或者只是一个填充的对象。UPD | 显示 和 生成器之间差异的代码示例
map
:通过功能
map
:通过生成器:
简单来说,当需要对对象进行操作(方法、算术运算)或者需要
map
转换对象时,即从技术上讲,转换对象本身不被保存时,最好使用生成器。从英文答案翻译到Python.org 上的讨论
如果只有一种“明显的方法来做到这一点”,那就太好了,但这几乎是不可能的。不同的事情对不同的人来说似乎是显而易见的。这条规则更多的是针对语言开发人员而不是程序员:当有一个常见任务需要多行代码,并且人们编写代码的方式不同,并且每种方式都需要一点思考......那么最好让语言提供更明确的支持。即使每个人都这样做,也不应该显得太抽象。遵循这一原则,我们可以获得令人愉快的便利设施,例如
random.choice
。至于
map
与列表包含的比较,这是我(Karl Knechtel)的个人指南:列表包含通常是首选。
使用
map
时:当您还需要过滤时,列表包含特别好:
在Python3中
map
它是“懒惰的”。如果您需要此延迟结果,但想要使用列表包含语法,请改为编写生成器表达式:生成的生成器对象可以按照与显示结果相同的基本方式使用。(存在技术差异,但在这里并不重要。)