Python 中的生成器

原文:https://www.studytonight.com/python/python-generators

在开始本教程之前,您应该学习什么是 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,每个值都是平方的。我们没有创建方块列表,而是直接打印结果,不需要存储单个值。