要了解 yield 的作用,您必须了解生成器是什么。在你理解生成器之前,你必须理解迭代。
可迭代对象
创建列表时,您可以一一阅读其项目。一项一项地读取它的项称为迭代:
>>> 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...”的所有内容都是可迭代的;列表、字符串、文件...
这些可迭代对象很方便,因为您可以随心所欲地读取它们,但是您将所有值存储在内存中,当您有很多值时,这并不总是您想要的。
发电机
生成器是迭代器,一种只能迭代一次的可迭代对象。生成器不会将所有值存储在内存中,它们会即时生成值:
>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator:
... print(i)
0
1
4
除了使用 () 而不是 [] 之外,它是一样的。但是,您不能在 mygenerator 中执行 for i 第二次,因为生成器只能使用一次:它们计算 0,然后忘记它并计算 1,然后一个一个地结束计算 4。
屈服
yield 是一个与 return 一样使用的关键字,除了该函数将返回一个生成器。
>>> def createGenerator():
... mylist = range(3)
... for i in mylist:
... yield i*i
...
>>> mygenerator = createGenerator() # create a generator
>>> print(mygenerator) # mygenerator is an object!
<generator object createGenerator at 0xb7555c34>
>>> for i in mygenerator:
... print(i)
0
1
4
这是一个无用的示例,但是当您知道您的函数将返回大量值而您只需要读取一次时,它会很方便。
要掌握yield,你必须明白,当你调用函数时,你写在函数体中的代码是不会运行的。该函数只返回生成器对象,这有点棘手:-)
然后,您的代码将从每次停止的地方继续使用生成器。
现在最困难的部分:
第一次 for 调用从你的函数创建的生成器对象时,它会从头开始运行你的函数中的代码,直到它达到 yield,然后它会返回循环的第一个值。然后,每个后续调用将运行您在函数中编写的循环的另一次迭代并返回下一个值。这将一直持续到生成器被认为是空的,这发生在函数运行时没有达到产量时。这可能是因为循环已经结束,或者因为您不再满足“if/else”。
Python 由兴高采烈的针鼹