Python生成器有些难以用语言表达其概念,所以在这里用几段代码来解释~
生成器:任何包含yield语句的函数称为生成器;
生成器是一种普通的函数语法定义的迭代器。
def test2(): print 9 print 8 yield 7 test2()
上述代码什么都不返回,因为代码碰到了yield函数暂停(或冻结)了,这个暂停同时还影响了yield以上的两个print。
def test2(): print 9 print 8 yield 7 t2 = test2() t2.next() -------------------------------------------------------------------------------- [root@xfwy tmp]# ./1.py 9 8
通过使用next方法,激活了yield,这样被yield暂停的两条print语句得以输出。
但是,yield后的7是什么?看样子是想要输出的,但是怎么没有输出?
这是因为,使用next方法,只是让冻结内容继续执行,而yield只是激活了,而它自身并不会输出它后边的值,而是保存下来。
那这里yield已经将值保存出来了,怎么输出呢~
def test2(): print 9 print 8 yield 7 t2 = test2() print t2.next() -------------------------------------------------------------------------------- [root@xfwy tmp]# ./1.py 9 8 7
对的,只需要一个print,以上两段代码就可以看出来,t2.next()只是将暂停继续(激活),并保存yield的值,而yield语句并不会输出值,这样就得使用print来打印出值。
这样,大致的yield的概念清楚了,我们就理解下下边这个二层嵌套列表的生成器了
def flt(nes): for i in nes: for j in i: yield j nested = [[1, 2], [3, 4], [5]] for num in flt(nested): print num print "---------" print list(flt(nested)) -------------------------------------------------------------------------------- [root@xfwy tmp]# ./1.py 1 2 3 4 5 --------- [1, 2, 3, 4, 5]
因为生成器有个概念为“生成器是一种普通的函数语法定义的迭代器”。所以生成器就是迭代器且可被迭代。
函数flt()的两层for循环很清楚,就是从一个二层嵌套表中取元素。上述代码是用迭代for循环取元素,取一个元素,操作一个元素。
所以,yield作用就是,yield语句在的话,yield语句是整个函数的主权,所有代码不管你yield代码前返回什么或者打印什么,都会被暂停,直到有激活出现。