生成器

1.什么是生成器?
一边循环一边推算后续元素的机制,叫做生成器(generator)。
与列表生成器的区别就在于不用一次性生成所有的元素,从而节省了空间。
函数中含有yield关键字的函数就是生成器函数,生成器函数返回一个生成器对象。生成器中的yield相当于普通函数中的return作用,运行生成器函数的时候,每次遇到yield就会暂停并保存当前所有的运行信息,再次执行next()方法的时候从当前位置开始执行,知道再次遇到yield停止。
注意:迭代器只能迭代一次。
2.创建生成器
*生成器表达式

g = (i for i in range(10))
print(g)
for i in range(10):
    print(next(g))

*生成器函数

def odd():
    print("step 1")
    yield 1
    print("step 2")
    yield 2
    print("step 3")
    yield 3
odd = odd()
print(odd.__next__())
print(odd.__next__())
print(odd.__next__())

#斐波那契函数的应用
def fbi(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a+b
        n = n+1
max = 6
fbi = fbi(max)
#第一种表达方式
for i in range(max):
    print(fbi.__next__())
#第二种表达方式,捕获异常方式
while True:
    try:
        print(next(fbi))
    except StopIteration as e:
        print("Generator return value:",e.value)
        break

3.使用案例

'''
将population中的人口数量求和,和获取某个城市人口占总人口的比例
思路:1)因为文件比较大的时候使用readlines方法的话影响效率,所以使用生成器函数一行一行读取返回
      2)因为从文档中读取的数据是str类型,所以使用eval方法将str转换成字典数据类型
      3)定义一个sum方法,将每行的数据累加
'''

def get_population():
    with open('population','r',encoding='utf-8') as f:
        for line in f:
            #将读取出来的str通过eval()函数转换为字典
            yield eval(line)

def sum_population():
    g = get_population()
    sum_population = sum(i["population"] for i in g)
    return sum_population

def sum_population1():
    sum_population = 0
    g = get_population()
    for i in g:
        sum_population = sum_population + i["population"]
    return sum_population

def get_sigle_city_percent():
    g = get_population()
    for i in g:
        print('%s的人口比例是:%s' % (i["city"],i["population"]/sum_population()))

print(sum_population())
print(sum_population1())
print(get_sigle_city_percent())

4.生产者消费者模型

import time

def consumer(name):
    print("我是 %s ,我准备吃包子了" % name)
    while True:
        baozi = yield
        time.sleep(1)
        print("%s 很开心的吃了【%s】包子" % (name,baozi))

def producer():
    c1 = consumer('zhangzhang')
    c2 = consumer('kpfshe')
    c1.__next__()
    c2.__next__()
    for i in range(10):
        time.sleep(1)
        c1.send("肉包子 %s" % i)
        c2.send("菜包子 %s" % i)

producer()
image.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容