首页 > 编程语言 > 详细

python中的生成器

时间:2015-03-24 23:19:27      阅读:537      评论:0      收藏:0      [点我收藏+]

生成器表达式和列表解析:

(x+1 for x in [1,2,3,4,5])   #生成器表达式
[x+1  for x in [1,2,3,4,5]]  #列表解析
(x+1 for x in [1,2,3,4,5,6] if x>0)
((x,y) for x in range(3) for y in range(x))
(x for x in (y.dosomething() for y in [1,2,3,4,5]) if x>0)

一个带有yield的函数就是一个generator,它和普通函数不同,生成一个generator看起来像函数调用。但不会执行任何函数代码,直到对其调用next()(在for循环中会自动调用next())才会开始执行。虽然执行流程仍然按函数的流程执行,但每执行到一个yield语句就会中断,并返回一个迭代至,下次执行时从yield的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被yield中断了数次。每次中断都会通过yield返回当前的迭代值。

如,输出斐波那契数列:

def fab(max):
    a=0
    b=1
    i=0
    while(i<max):
        yield b
        a,b=b,a+b
        i=i+1
        
for i in fab(5):
    print i

判断一个函数是否是一个特殊的generator函数:

>>>from inspect import isgeneratorfunction
>>>isgeneratorfunction(fab)

fab是一个generator function,而fab(5)是调用fab返回的一个generator ,好比是类和类的实例的区别。

>>>import types
>>>isinstance(fab,types.GeneratorType)
False
>>>isinstance(fab(1),types.GeneratorType)
True

return的作用:

作为生成器,因为每次迭代就会返回一个值,所以不能显示的在生成器函数中return某个值,包括None的值也不行,但在函数中可以出现单独的return,表示结束该语句。

send()和next()函数:

其实,next()和send()在一定意义上作用是相似的,区别是send()可以给yield表达式传递值,而next()不可以,只能传递None进行。因此,我们可以看作c.next()和c.send(None)是一样的。

def a(n):
    while True:
        b=yield n
        print b
>>>b=a(5)
>>>b.next()
5
>>>b.next()
None
5
>>>c=a(5)
>>>c.next()
5
>>>c.send(3)
3
5

由此可见,yield表达式的值是由send函数传递的值决定的,而yield返回的值不受影响。

def a(n):
    i=0
    while i<n:
        i=yield i
        i=i+1
>>>b=a(10)
>>>a.next()
0
>>>a.next()
出现TypeError的错误
>>>c=a(5)
>>>c.next()
0
>>>c.send(2)
3       #此时,传入2,则i=2,然后执行i=i+1,i变成了3,yield返回3
>>>c.send(9)
出现StopIteration的异常

采用yield读取文件:

如果直接读取文件,会导致不可预测的内存占用。好的方法就是利用固定长度的缓存来不断的读取文件的内容。通过yield,我们不再需要编写读文件的迭代类就可以轻松实现文件读取:

def read_file(fpath):
    block_size=1024
    with open(fpath) as f:
        while True:
            block=f.read(block_size)
            if block:
                yield block
            else:
                return


python中的生成器

原文:http://my.oschina.net/935572630/blog/391034

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!