生成器
通过列表生成式,可以直接创建一个列表,但是,受到内存限制,列表容量肯定是有限得。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。所以,如果列表元素可以按照某种算法推算出来,那是否可以在循环的过程中不断推算出后续的元素呢,这样就不必创建完整的列表,从而节省大量的空间,在python中,这种一边循环一边计算的机制,称为生成器。
列表生成式-- [ i*2 for i in range(5) ] --> [0,2,4,6,8] 可以通过索引和切片来取任何一个元素
生成器-- ( i*2 for i in range(5) ) 只能通过循环来取的时候才一个一个的创建出来,只能往后取,不能取前面已经读取的。只有一个__next__()方法,取当前位置的下一个元素
generator非常强大,如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。
例如斐波拉契数列,除了第一个和第二个数外,任意一个数都可由前两个数相加得到。
def fib(max): n,a,b = 0,0,1 while n < max: print(b) a,b = b,a+b n = n+1 return "done"
转变成生成器:
def fib(max): n,a,b = 0,0,1 while n < max: yield b a,b = b,a+b n = n+1 return "done"
这样取值可以通过__next__一个一个的取,其中可以执行其他的代码,取过的元素就不能再去访问了
生成器单线并行
import time def consumer(name): print("%s 准备吃包子" %name) while True: baozi = yield print("包子[%s]来了,被[%s]吃了" %(baozi,name)) def producer(name): c = consumer('A') c2 = consumer('B') c.__next__() c2.__next__() print("开始做包子") for i in range(10): time.sleep(1) print("做了2个包子") c.send(i) c2.send(i) producer("chy")