我试图在许多教程中理解Python生成器的人告诉他们它们比例如迭代列表快得多,所以我试一试,我写了一个简单的代码。我没想到那个时差会那么大,有人可以解释一下为什么吗?或许我在这里做错了。
def f(limit):
for i in range(limit):
if(i / 7.0) % 1 == 0:
yield i
def f1(limit):
l = []
for i in range(limit):
if(i / 7.0) % 1 == 0:
l.append(i)
return l
t = timeit.Timer(stmt="f(50)", setup="from __main__ import f")
print t.timeit()
t1 = timeit.Timer(stmt="f1(50)", setup="from __main__ import f1")
print t1.timeit()
结果: t = 0.565694382945 t1 = 11.9298217371
答案 0 :(得分:3)
您没有公平地比较f
和f1
。
您的第一个测试只是测量Python 构建生成器对象需要多长时间。它永远不会迭代这个对象,这意味着f
中的代码永远不会被实际执行(生成器只在迭代时执行它们的代码)。
然而,您的第二个测试会测量拨打f1
所需的时间。意思是,它计算函数构造列表l
所需的时间,运行for循环完成,多次调用list.append
,然后返回结果。显然,这将比生成生成器对象慢得多。
为了公平比较,请将生成器f
转换为列表:
t = timeit.Timer(stmt="list(f(50))", setup="from __main__ import f")
这将导致它完全迭代,这意味着现在将执行f
内的代码。
答案 1 :(得分:1)
您计算创建生成器对象所需的时间。创建一个实际上并不执行任何代码,因此您实际上只是按照精心设计的方式执行任何操作。
修复之后,您会发现运行完成时生成器通常会稍微慢一些。它们的优点是它们不需要同时将所有元素存储在内存中,并且可以在中途停止。例如,当你有一系列布尔值并且想要检查它们中是否有任何一个是真的时,你需要首先计算所有值并创建一个列表,然后再检查真相,而对于生成器,你可以:
答案 2 :(得分:1)
https://wiki.python.org/moin/Generators在改进的效果部分提供了一些很好的信息。虽然创建一个生成器可能需要一些时间,但它提供了许多优点。
这是一个关于创建生成器和迭代器http://sahandsaba.com/python-iterators-generators.html的好教程。看看吧!