原则上,生成器由于其惰性求值而节省内存。
一个
生成器非常类似于返回数组的函数,它具有参数、可以被调用,并生成一系列的值。但是,与构建包含所有值并立即返回它们的数组不同,生成器逐个
yield
值,这需要更少的内存,并允许调用者立即开始处理前几个值。
简而言之,生成器看起来像一个
function
,但行为像一个
iterator
。
from itertools import count
itertools
提供了 count
方法,可以生成无限的整数流。你可以指定起始值和步长来生成这个流。下面是一个使用示例。
for i in count(start=0, step=1):
print i
一个生成偶数列表的简单示例。
构建并返回一个列表:
def find_even_number_function(number_stream):
even_number = []
for n in number_stream:
if n % 2 == 0:
even_number.append(n)
return even_number
for i in find_even_number_function(count()):
print i
这段代码非常简单和直接,但是它在内存中构建了完整的列表。在我们的情况下,这显然是不可接受的,因为我们无法承受将无限整数保存在内存中。正如你所看到的,该函数永远不会停止。在这种情况下,我们将使用生成器。
生成器使用yield
来产生项目,而不是返回列表。
def find_even_number_generator(number_stream):
for n in number_stream:
if n % 2 == 0:
yield n
for i in find_even_number_generator(count()):
print i
请注意,数字生成逻辑的表达清晰自然。它非常类似于在内存中构建列表的实现,但具有迭代器实现的内存使用特性。
使用生成器带来的性能提升是惰性(按需)生成值的结果,这意味着内存使用更少。此外,我们不需要等到所有元素都被生成才开始使用它们。这类似于迭代器提供的好处,但生成器使构建迭代器变得容易。
因此,简单地说,如果您对上述情况使用普通函数,您将耗尽内存。或者,如果您使用生成器函数,则会耗尽时间。