生成器

通过列表生成式,可以很方便的创建生成一个列表。但是当我们一次要创建一个一百万条数据的列表的时候,那么就会非常占用存储空间,所以如果列表元素可以按照某种算法推算出后续的元素,那么就可以节省很大的空间,这种一边循环一边计算的机制,成为生成器:generator
 
生成器可以使用next()方法来获取下一个元素,当获取完毕后再次获取会抛出可以用对象的__next__(),内置方法来获取生成器的值
 
生成器,只有在调用时才会生成相应的数据
 
创建一个generator,有很多办法:
1、利用列表生成式,创建生成器g
1 g = (x for x in range(10) )
2 >>> g
3 <generator object <genexpr> at 0x0344A480>
4 >>> 
 
2、利用函数,创建生成器(yield)
生成器于普通函数不同的地方是,生成器利用yield返回,而函数利用return来返回
函数遇到yield关键字后,会直接返回,下次执行后,继续执行yield后面的代码,直到再次遇见yield后返回
1 >>> def test():
2 n = 0
3 while n < 10:
4 yield n
5 n += 1
6 >>> test()
7 <generator object test at 0x0344A4B0>
 
例子:斐波那契序列:
1,1,2,3,5,8,13...... 前面的两个数相加等于第三个数,这就是著名的斐波那契序列.
1  
2 def fib(num):
3   n,a,b=0,0,1
4   while n < num:
5     print(b)
6     a,b = b,a+b -->这里的原理是,预先 t = (b,a+b) ,然就在a=t[0],b=t[1]
7     n+=1
8 fib(6)
9  
 
注意:
1、如果函数被改造成生成器,那么函数的return语句返回的将是异常提示信息,如果我们在生成器中return 'test',那么我们调用next()方法直到数据读取完毕后,会抛出StopIteration:test的异常!
2、生成器属于懒惰序列,如果不去循环的调用、或者使用next方法去获得元素,它是不会去加载后面的数据的,如果我们现在需要加载,那么可以通过list(),把生成器的数据转换成list输出即可。
1 def gen():
2   q,n = 0,1
3   while q < 10:
4     yield n
5     n+=1
6     q+=1
7 print(list(gen()))
原文地址:https://www.cnblogs.com/dachenzi/p/6626703.html