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代码前返回什么或者打印什么,都会被暂停,直到有激活出现。