Python 中的生成器
在开始本教程之前,您应该学习什么是 yield 关键字和什么是 iterable&迭代器,因为这些概念将在这里使用。
一个生成器只不过是一个使用yield关键字而不使用return语句返回值的函数。
如果我们必须编写一个自定义迭代器,你将必须实现__iter__()和__next__()方法,定义通过保持状态返回下一个值的机制,并且当没有更多的值可以迭代时引发StopIteration异常。
好吧,生成器让创建一个状态保持的迭代器变得超级容易,你所要做的就是使用yield关键字返回数据。
任何包含yield关键字的函数都将成为一个生成器,并将返回一个迭代器对象,该对象可以使用for循环进行迭代。
创建 Python 生成器
将简单函数转换成生成器函数的神奇方法是yield关键字。我们可以有一个或多个yield语句从生成器返回一些数据,每次调用生成器时yield语句存储局部变量的状态并产生一个结果。
这里有一个简单的例子,
在上面的例子中,我们定义了一个名为new_gen()的 python 生成器,其中我们取一个变量n给它赋值,打印一些东西,然后产生一个值。在函数内部,我们已经重复了 3 次。
如果我们试图像普通函数一样调用一个生成器函数,它不会被执行,因为它返回一个迭代器对象。因此,我们使用变量x来存储迭代器对象,然后使用next()方法来执行该方法。并且每次生成器的执行都是从它最后离开的地方开始的,即最后的yield语句。
屈服于 Python 列表
我们可以直接使用生成器通过生成值来形成列表,如下例所示,我们已经使用生成器生成了一系列值,并将生成器生成的值存储到列表mylist中。
# defining a generator
def generator():
x = 0
while x < 5:
yield x
x += 1
# yielding values directly into a list
mylist = list(generator())
# use for loop to print mylist items
for x in mylist:
print(x)
0 1 2 3 4
生成器对普通函数对 Python 列表
生成器和简单函数之间的主要区别在于生成器产生值而不是返回值。换句话说,一个简单的函数只返回一个变量,然后就结束了,但是生成器可以通过提供一个迭代器对象来产生一系列的值,我们可以在这个对象上进行迭代。
一个生成器必须有一个yield语句,否则它只是一个正常的函数。
当生成器生成时,它存储其局部变量状态并将控件返回给调用方。当它再次被调用时,它从上次调用中离开的地方开始。正常的函数不支持这种行为。
现在我们来谈谈生成器和列表之间的区别。最大的区别也是生成器最大的优势是生成器从不存储任何值;它只是一个接一个地产生值,因此节省了空间和时间,这不是列表的情况。
带循环的 Python 生成器
作为一个生成器返回一个迭代器对象,因此我们可以使用像for循环这样的循环来迭代它,并打印产生的值。
让我们举一个简单的例子:
Python 中的生成器表达式
就像列表理解一样,我们可以使用表达式来创建 python 生成器的速记。例如,
data = [0, 1, 2, 3, 4]
# creating a generator using generator expression
new_generator = (x*x for x in range(5))
for each in new_generator:
print(each)
0 1 4 9 16
在上面的例子中,生成器表达式生成一个迭代器,它类似于列表data,每个值都是平方的。我们没有创建方块列表,而是直接打印结果,不需要存储单个值。