为什么Python中对于长列表的短列表进行双重循环比在长列表中的相同操作更快?
考虑以下示例:
from datetime import datetime as dt
def long_short(n):
"""Iterate through n long list of 10 long lists"""
x = [["inner"]*10]*n
start = dt.now()
counter = 0
for i in x:
for j in i:
counter += 1
return (dt.now() - start).microseconds/1000
def short_long(n):
"""Iterate through 10 long list of n long lists"""
x = [["inner"]*n]*10
start = dt.now()
counter = 0
for i in x:
for j in i:
counter += 1
return (dt.now() - start).microseconds/1000
x, y1, y2 = [], [], []
for i, n in enumerate(range(1000, 1000000, 10000)):
x.append(n)
y1.append(long_short(n))
y2.append(short_long(n))
print n,
plt.figure()
ax1 = plt.plot(x, y1, c="b", label="Long list of short lists")
ax2 = plt.plot(x, y2, c="g", label="Short list of long lists")
plt.xlabel("n", fontsize=16)
plt.ylabel("Time (ms)", fontsize=16)
plt.legend(loc=2, fontsize=14)
plt.show()
这将产生数字:
我知道这是一个极端的例子,因为很少需要循环遍历这么大的嵌套列表,但是我再次想象矩阵操作需要通过{{1}上的双循环来访问每个元素}和range(N)
,对于这种情况,这个结果表明应该将最短循环保持为外循环。
修改
我最初在标题和上面的书面文字中切换了结果。我更新了标题和文字以纠正这个问题。此错误导致代码和图形保持不变!
正如原始问题the accepted answer中指出的那样,性能差异的原因很简单,当在一个短列表中进行双循环时,创建了一个内部for循环时间而不是相反的情况。