python - 为什么列表理解在转置矩阵中胜过 zip

标签 python performance zip list-comprehension

最近我正在使用 python 处理数百万大小的列表。

这里我有一个列表E,它有 1,470,000 个元素,每个元素都是一个包含 2 个整数的列表。

E 看起来像:[[1, 3], [2, 4], [4, 7] ... ]

我想分别获取第一列和第二列的最大数量。

我可以通过列表推导得到它

m1 = max([e[0] for e in E])
m2 = max([e[1] for e in E])
return (m1, m2)

另一种方法是使用 zip:

list(map(max, zip(*E)))

起初我认为第二种方式应该更快,因为列表理解将构建一个大列表(而且,2 次)。但事实证明列表理解速度非常快,使用 zip 的方法要慢大约 10 ~ 20 倍(使用 cProfile)。

我认为 zip 不应该那么慢,(而且,列表理解怎么可能那么快?)谁能告诉我原因吗?

我正在使用 python 3.2

附言通过使用 Windows 任务管理器,我什至看不到任何内存跟踪显示 python 曾经创建过一个新列表。一定有黑魔法。

最佳答案

我已经使用 Python 2.7.3 和 3.3.0 测试了多种方法,但我无法重现您的结果。

以下时间来自 Python 2.7.3(3.3.0 的结果类似):

In [31]: E = [(random.randrange(0,1000),random.randrange(0,1000)) for _ in range(1470000)]

In [32]: %timeit max([e[0] for e in E]), max([e[1] for e in E])
1 loops, best of 3: 319 ms per loop

In [33]: %timeit max(e[0] for e in E), max(e[1] for e in E)
1 loops, best of 3: 343 ms per loop

In [36]: %timeit max(E, key=operator.itemgetter(0)), max(E, key=operator.itemgetter(1))
1 loops, best of 3: 314 ms per loop

In [38]: %timeit list(map(max, zip(*E)))
1 loops, best of 3: 307 ms per loop

我测试过的所有方法都具有大致相同的性能。

如果您关心性能,您应该考虑使用 NumPy:

In [39]: import numpy as np

In [40]: EE = np.array(E)

In [46]: %timeit EE.max(axis=0)
100 loops, best of 3: 3.21 ms per loop

如您所见,在此数据集上,numpy.max() 比我尝试过的任何纯 Python 方法快大约 100 倍。

关于python - 为什么列表理解在转置矩阵中胜过 zip,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13929407/

相关文章:

python - 不使用 numpy 求矩阵中所有行的列总和

python - 如何访问 SymPy 中获得的线性方程组解?

javascript - Jquery 性能动态创建巨大的表

javascript - id太多会影响性能吗

java - 从数据库读取 zip 存档

python - "with psycopg2.connect"是否自动关闭连接?

python - 检查 Python 的 `Counter` 中的元素数量

java - 关于Java重数学计算的问题

Python 暴力破解 zip 文件

python - 如何以内存高效的方式将大量文件添加到 zip?