python入门之生成器

生成器

  通过列表生成式,可以直接创建一个列表,但是,受到内存限制,列表容量肯定是有限得。而且,创建一个包含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")

 

posted @ 2018-12-26 15:49  _chy  阅读(188)  评论(0编辑  收藏  举报