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