哈Ha 通常,在处理序列时,问题就在于它们的创建。 它似乎习惯于使用
列表包含(List Comprehension) ,并且在书中大声喊着强制使用内置
地图功能。
在本文中,我们将考虑使用这些方法处理序列,比较性能以及确定在哪种情况下哪种方法更好。
清单理解
列表包含是Python内置的列表生成机制。 他只有一项任务-建立清单。 列表包含可从任何可迭代类型构建列表,从而转换(过滤)传入的值。
一个简单的列表包含示例,用于生成一个从0到9的数字平方:
squares = [x*x for x in range(10)]
结果:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
地图
map是语言内置的功能。 它接受一个函数作为第一个参数,并接受一个可迭代的对象作为第二个参数。 返回一个生成器(Python 3.x)或一个列表(Python 2.x)。 我将选择Python 3。
调用map函数以生成一个从0到9的数字平方的列表的示例:
squares = list(map(lambda x: x*x, range(10)))
结果:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
性能比较
没有功能的构建
作为实验,我们将考虑从0到9,999,999区间的数字平方:
python -m timeit -r 10 "[x*x for x in range(10000000)]" python -m timeit -r 10 "list(map(lambda x: x*x, range(10000000)))"
结果:
1 loop, best of 10: 833 msec per loop 1 loop, best of 10: 1.22 sec per loop
如您所见,
List Comprehension方法的运行速度提高了约32%。 分解后,不可能获得完整的答案,因为map函数“似乎隐藏了其工作的细节”。 但这很可能是由于lambda函数的不断调用,在该函数内部已经进行了平方计算。 对于列表理解,我们只需要计算平方。
使用功能构建
为了进行比较,我们还将考虑数字的平方,但是计算现在将在函数内部:
python -m timeit -r 10 -s "def pow2(x): return x*x" "[pow2(x) for x in range(10000000)]" python -m timeit -r 10 -s "def pow2(x): return x*x" "list(map(pow2, range(10000000)))"
结果:
1 loop, best of 10: 1.41 sec per loop 1 loop, best of 10: 1.21 sec per loop
这次情况相反。
映射方法快14%。 在此示例中,两种方法处于相同情况。 两者都必须调用一个函数来计算平方。 但是,通过对地图函数进行内部优化,可以显示出更好的结果。
选择什么?
以下是选择正确方法的规则:

该规则可能会有例外,但是在大多数情况下,它将帮助您做出正确的选择!
地图“更安全”吗?
为什么许多人敦促使用
地图 。 事实是,在某些情况下,地图实际上比列表理解更安全。
例如:
symbols = ['a', 'b', 'c'] values = [1, 2, 3] for x in symbols: print(x) squared = [x*x for x in values]
该程序的输出如下:
a 3 b 3 c 3
现在,使用
map重写相同的代码:
symbols = ['a', 'b', 'c'] values = [1, 2, 3] for x in symbols: print(x) squared = map(lambda x: x*x, values)
结论:
a a b b c c
从使用
map的语法中,最细心的人可能已经注意到这是Python2。确实,在第二个python中,存在类似的变量覆盖问题。 但是,在Python 3中,此问题已修复,不再相关。
上述示例将显示相同的结果。 似乎这也是一个愚蠢的错误,您永远不会犯这样的错误,但是,当您只是从另一个块中转移一个带有内部循环的代码块时,就可能发生这种情况。 这样的错误可能会花费您很多时间和精力来解决它。
结论
比较表明,每种方法在其情况下都很好。
- 如果您不需要一次所有的计算值(或者根本不需要它们),则应该选择map 。 因此,根据需要,您可以从生成器中请求一部分数据,同时节省大量内存(Python3。在Python 2中,这没有意义,因为map返回一个列表)。
- 如果您需要一次计算所有值并且可以在不使用函数的情况下完成计算,则应在List Comprehension的方向上做出选择。 如实验结果所示-它在性能方面具有明显优势。
PS:如果我错过了什么,很高兴在评论中与您讨论。