跳转至

1. yield关键字的作用

题目

"yield"关键字是做什么的?链接

回答一

想要理解yield关键字,你必须先理解generators是什么,理解generators之前要先理解iterables.

Iterables

当你创建一个list,你可以一个个的读其中的元素,一个一个读就叫做iteration:

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

这里的mylist就是一个iterable。当你用一个list,你先创建一个list,这就是一个iterable:

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

任何你使用“for...in...”的地方就是一个iterable;例如lists,strings,files... 这些iterables使用很方便。因为你可以想读多少读多少,但是你需要把它们都存在内存里面,当你有很多值的时候这样可能就不太好了。

Generators

Generators也是iterators,是一种只能遍历一遍的iterable,Generators并不把所有值都存在内存里,而是在遍历过程中生成这些值:

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

这个和使用list一样只是你用()而不是[],只是你不能再次使用形如for i in mygenerator因为它只能被使用一次,它从0开始计算,然后抛弃它再计算1,一个接一个。

Yield

yield是一个关键字类似return的用法,一个函数使用时会返回一个generator。

>>> 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,你需要明白当你调用这个函数的时候,你写的代码并没有实际地在run,而只是返回了一个generator的对象,这里有一些tricky。

然后,你的代码会在每一次for循环使用这个generator的时候run起来。

接下来,最难的部分:

当for循环第一次调用这个generator的时候,你的代码会从最开始运行,直到yield语句,然后他会返回这个循环的第一个值。然后每一次调用,都会再一次运行这个function并且返回下一个值,直到没有值可以返回。 一旦这个function运行到再也不会hit yield语句,这个generator会被视为空,因为这个时候循环结束了,或者你不满足你的if else语句了。