python生成器

生成器就是一个函数,python中带yield关键字的函数就是一个生成器。yield语句就是返回一个对象(值),和普通的函数用return返回值不同如果想取得值,那得调用next()函数,如:

c = h() #h()包含了yield关键字  
#返回值  
c.next()


每当调用一次迭代器的next函数,生成器函数运行到yield之处,返回yield后面的值且在这个地方暂停,所有的状态都会被保持住,直到下次next函数被调用,或者碰到异常循环退出。

生成器在内部记住了记住上一次返回时在函数体中的位置。对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量和函数参数都保持不变。生成器不仅“记住”了它的数据状态;生成器还“记住”了它在流控制构造(在命令式编程中,这种构造不只是数据值)中的位置。

其实说白了就是,生成器记录了上次调用的数据与执行流程。
def fib(max):  
    a, b = 1, 1  
    while a < max:  
        yield a #generators return an iterator that returns a stream of values.  
        a, b = b, a+b
        print "a=",a,"b=",b  
for n in fib(15):  
    print n  

通过使用生成器的语法,可以免去写迭代器类的繁琐代码,如,上面的例子使用迭代类来实现,代码如下:

class Fib:  
    def __init__(self, max):  
        self.max = max  
    def __iter__(self):       #定制可迭代类重载__iter__
        print "iter"  
        self.a = 0  
        self.b = 1  
        return self  
    def next(self):           #定制可迭代类重载next()  
        print "next"  
        fib = self.a  
        if fib > self.max:  
            raise StopIteration  
        self.a, self.b = self.b, self.a + self.b  
        return fib  

for i in Fib(5):
    print i




#yield其他例子展示:排列,组合
#生成全排列    
def perm(items, n = None):  
    if n is None:  
        n = len(items)  
    for i in range(len(items)):  
        v = items[i:i+1]  
        if n==1:  
            yield v  
        else:  
            rest = items[:i] + items[i+1:]  
            for p in perm(rest, n-1):  
                yield v + p

def comb(items, n = None):  
    if n is None:  
        n = len(items)  
    else:  
        for i in range(len(items)):  
            v = items[i:i+1]  
            if 1 == n:  
                yield v  
            else:  
                rest = items[i+1:]  
                for c in comb(rest, n-1):  
                    yield v + c  

生成器语法
生成器表达式是在python2.4中引入的,当序列过长, 而每次只需要获取一个元素时,应当考虑使用生成器表达式而不是列表解析。

生成器表达式的语法和列表解析一样,只不过生成器表达式是被()括起来的,而不是[],如下: 

(expr for iter_var in iterable) 
(expr for iter_var in iterable if cond_expr) 

>>> L= (i + 1 for i in range(10) if i % 2) 
>>> L 
<generator object <genexpr> at 0xb749a52c> 
>>> L1=[] 
>>> for i in L: 
... L1.append(i) 
... 
>>> L1 
[2, 4, 6, 8, 10] 

生成器表达式并不真正创建数字列表, 而是返回一个生成器,这个生成器在每次计算出一个条目后,把这个条目“产生”(yield)出来。
生成器表达式使用了“惰性计算”,只有在检索时才被赋值( evaluated),所以在列表比较长的情况下使用内存上更有效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值