我预计,在多重循环列表进行迭代的情况下,会比使用生成快得多,和我的代码表明这是假的了发电机迭代多次。速度相比于列表
我的理解是(通过操作我的意思是定义一个元素任意表达式):
- 列表需要ň操作进行初始化
- 但随后在列表中的每个循环就可以抓取从存储器
- 从而一个元件,米遍历列表仅需要ñ操作
- 发电机不需要任何操作来进行初始化
- 然而,上循环发电机运行在飞行操作
- 因此,一个循环在发电机需要ň操作
- 但米遍历发电机需要的n×m操作
我用下面的代码检查了我的期望:
from timeit import timeit
def pow2_list(n):
"""Return a list with powers of 2"""
results = []
for i in range(n):
results.append(2**i)
return results
def pow2_gen(n):
"""Generator of powers of 2"""
for i in range(n):
yield 2**i
def loop(iterator, n=1000):
"""Loop n times over iterable object"""
for _ in range(n):
for _ in iterator:
pass
l = pow2_list(1000) # point to a list
g = pow2_gen(1000) # point to a generator
time_list = \
timeit("loop(l)", setup="from __main__ import loop, l", number=10)
time_gen = \
timeit("loop(g)", setup="from __main__ import loop, g", number=10)
print("Loops over list took: ", time_list)
print("Loops over generator took: ", time_gen)
而且结果让我吃惊......
Loops over list took: 0.20484769299946493
Loops over generator took: 0.0019217690005461918
不知怎的,使用发电机循环1000次以上,即使出现比列表更快。在这种情况下,我们谈论的是两个数量级!为什么?
编辑:
感谢您的答案。现在,我看到我的错误。我错误地认为发电机从一个新的循环开始,如范围:
>>> x = range(10)
>>> sum(x)
45
>>> sum(x)
45
但这是天真的(范围不是发电机...)。
关于可能的重复评论:我的问题涉及到生成器的多个循环,这在其他线程中没有解释。
你假设生成器更快是不正确的。可能的重复[生成器与Python中的列表理解性能](http://stackoverflow.com/questions/30112326/generators-vs-list-comprehension-performance-in-python) – AChampion
速度差异是两个数量级的差异应该提醒你注意事项,即你的测试有问题。试试'loop(pow_2_gen(1000))'以获得准确的结果。 – Dunes
您的测试是否有瑕疵。一个函数必须在内存中创建一个完整的列表,另一个函数只能返回一个迭代器。建议使用@Dunes来获得更准确的结果。 –