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()