Python中yield关键字的作用


Python中yield关键字的作用

要了解yield它的作用,您必须了解生成器是什么。要理解生成器先理解迭代器iterables。

迭代器Iterables

创建列表时,您可以逐个读取其项目。逐个读取它的项称为迭代:

>>> mylist = [1, 2, 3]
>>> for i in mylist:
...    print(i)
1
2
3

mylist是一个可迭代的。当您使用列表推导时,您创建一个列表,因此是一个可迭代的:

>>> mylist = [x*x for x in range(3)]
>>> for i in mylist:
...    print(i)
0
1
4

你经常使用的内容都是可for... in...迭代的; lists,strings,文件...

这些迭代很方便,因为您可以根据需要读取它们,但是您将所有值存储在内存中,当您拥有大量值时,这并不总是您想要的。

生成器

生成器是迭代器,是一种只能迭代一次的迭代器。生成器不会将所有值存储在内存中,它们会动态生成值:

>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator:
...    print(i)
0
1
4

它只是相同的,除了你用()而不是[]。但是,由于生成器只能使用一次,所以不能再执行for i in mygenerator一次:它们计算0,然后忘记它并计算1,然后逐个计算4。

yield

yield是一个使用的关键字return,除了函数将返回一个生成器。

>>> def createGenerator():
...    mylist = range(3)
...    for i in mylist:
...        yield i*i
...
>>> mygenerator = createGenerator() # 创建生成器
>>> print(mygenerator) # mygenerator 是一个对象
<generator object createGenerator at 0xb7555c34>
>>> for i in mygenerator:
...     print(i)
0
1
4

这是一个无用的例子,但是当你知道你的函数将返回一组你只需要阅读一次的大量值时它会很方便。

要掌握yield,您必须明白,当您调用该函数时,您在函数体中编写的代码不会运行。该函数只返回生成器对象,这有点棘手:-)

然后,每次for使用生成器时都会运行代码。

现在困难的部分:

第一次for调用从函数创建的生成器对象时,它将从头开始运行函数中的代码直到它命中yield,然后它将返回循环的第一个值。然后,每个其他调用将再次运行您在函数中写入的循环,并返回下一个值,直到没有值返回。

一旦函数运行,该生成器被认为是空的,但不再被命中yield。这可能是因为循环已经结束,或者因为你不再满足"if/else"了。