python学习之生成器(generator)
生成器可以理解为一种数据类型,这种数据类型自动实现了迭代器协议
(其他的数据类型需要调用自己内置的__iter__方法),所以生成器就是
可迭代对象
生成器分类及在python中的表现形式:(python有两种不同的方式提供生成器)
1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回
结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便
下次从它离开的地方继续执行
def triangles():
a=[1]
while True:
yield a
a=[sum(i) for i in zip([0]+a,a+[0])]
n=0
for t in triangles():
print(t)
n=n+1
if n==10:
break
def product_baozi():
for i in range(1,10):
yield i
maibaozi=product_baozi()
print("吃包子:",next(maibaozi))
print("吃包子:",next(maibaozi))
2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象
而不是一次构建一个结果列表
优点:
Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才
产生结果,而不是立即产生结果。这也是生成器的主要好处。
三元表达式
‘二元‘ if name=="alex" else ‘三元‘
为真执行 判断 为假执行
列表解析
egg_list=[]
for i in range(10)
egg_list.append(‘eggs%s‘%i)
print(egg_list)
a=[‘eggs%s‘ i for i in range(10)]方括号换成圆括号就是生成器,取值内部a.__next__() next(4)
a2=(‘eggs %s‘ %i for i in range(10) if i>5)
print(a2)
print(type(a2))
print(next(a2))
print(next(a2))
总结:
1.把列表解析的[]换成()得到的就是生成器表达式
2.列表解析与生成器表达式都是一种遍历的编程方式,只不过生成器表达式更节省内存
3.生成器运行3种方式:__next__() next() seed()
4.yield 3相当于return控制的是函数的返回值
5.x=yield的另一个特性,接受send传过来的值,赋值给x
import time# def get_provice_population():# with open(r‘population.txt‘,‘r‘,encoding="utf-8") as f:# for line in f:# p=eval(line)# yield p[‘population‘]## gen=get_provice_population()# a1=[i for i in gen]# print(a1)# all_population=sum(a1)# for p in a1:# print("%0.2f %%"%(p/all_population))# def producer():# ret=[]# for i in range(10):# ret.append(‘包子%s‘%i)# return ret## def consumer(res):# for index,baozi in enumerate(res):# print(‘第%s个人,吃了%s‘%(index,baozi))## res=producer()# consumer(res)#单线程里并发,协程def producer(): ret=[] for i in range(10): ret.append(‘包子%s‘%i) return retdef consumer(name): #消费者 print(‘我是[%s],我准备开始吃包子了‘%name) while True: baozi=yield print(‘%s 很开心的把[%s]吃掉了‘%(name,baozi))def producer(): #生产者 c1=consumer(‘wupeiqi‘) c2 = consumer(‘zhao‘) c1.__next__() c2.__next__() for i in range(10): time.sleep(1) c1.send(‘baozi %s‘%i) c2.send(‘baozi %s‘%i)producer()