Python中的yield关键字做了什么 要理解yield做了什么,就必须明白生成器(generators)为何物,而在明白生成器之前还要知道迭代器(iterables)。 1.迭代器 当我们创建一个list的时候,我们可以一个接一个的读取它的成员。这种一个接一个读取的行为叫做迭代: >>>mylist = [1, 2, 3] >>>for i in mylist: ... print(i) 1 2 3 mylist就是一个迭代器。当我们使用列表推导式(亦称列表生成式,list comprehension)时,我们创建了一个list,同时还有一个迭代器: >>>mylist = [x*x for x in range(3)] >>>for i in mylist: ... print(i) 0 1 4 我们可以使用“ for … in …”的任何事物都是迭代器,如:列表、字符串、文件等。 这些迭代器很便利,我们可以想读取多少就读取多少,但是我们要在内存中储存所有的可取值,然而当我们有太多的值时我们不总是希望如此。 2.生成器 生成器(generators)也是迭代器,但是我们只能对其迭代一次。这是因为生成器并没有在内存中存储所有的值,而是要靠动态生成。 >>> mygenerator = (x*x for x in range(3))>>> for i in mygenerator:... print(i)014 我们用圆括号()代替了方括号[],除此之外是相同的。但是,我们不能重复执行for i in mygenerator,因为生成器只能使用一次:先计算出0,然后就忘了这个0并计算出1,最终计算出4。 3.yieldyield是一个关键字,使用起来类似return,但是使用的函数会返回一个生成器。 >>> def createGenerator():... mylist = range(3)... for i in mylist:... yield i*i...>>> mygenerator = createGenerator() # 创建一个生成器>>> print(mygenerator) # mygenerator是一个对象!>>> for i in mygenerator:... print(i)014 这是一个没用的例子,但是当我们知道我们的函数要返回一个庞大的值集合,而这些值我们只会迭代读取一次时,这样使用是很方便的。 要掌握yield,我们必须理解当我们在调用函数的时候,我们在函数体中写的代码并没有执行。函数仅返回了一个生成器对象,这有点意想不到。 然后,当for每次使用生成器的时候,我们的代码都会被执行一次。 重要的细节部分: 第一次for调用由我们的函数创建的生成器时,会从头执行我们函数中的代码直到遇见yield关键字,然后会返回循环的第一个值。其后每次调用都会再一次运行我们在函数中写的循环,返回下一个值,以此一直到再没有返回值。 一旦函数运行但不再激发yield时,就可以认为生成器已经空了。这可能是由于循环已经结束,或者由于我们不再满足“if/else”的条件判断。 本文版权归传智播客人工智能+Python学院所有,欢迎转载,转载请注明作者出处。谢谢!
作者:传智播客人工智能+Python学院
首发:http://python.itcast.cn/
|