四. python进阶(生成器,生成函数 )
一 .生成器
理解生成器 函数
只有含有yield的关键字都是生成器函数 但是不能和return共用 注意 yield只能在函数内部使用
生成器 本质就是迭代器
用到 处理很多数据时应用 yield 一条一条的返回数据
def aa(): print(1) yield "a" # 生成器函数:执行之后会得到一个生成器作为返回值 cc=aa() print(cc) # <generator object aa at 0x00000259830C2EB8> 生成器 print(cc.__next__()) # 1 a
def aa(): print(1) yield "a" print(2) yield "b" yield "c" cc=aa() g=cc.__next__() print(g) # 1 a g=cc.__next__() print(g) # 2 b g=cc.__next__() print(g) # c
def aa(): print(1) yield "a" print(2) yield "b" yield "c" c=aa() for i in c: print(i)
def dd(): for i in range(5): yield "生成50个哇哈哈%s"%i a=dd() for i in a: print(i) print("*************************************") def dd(): for i in range(21): yield "生成50个哇哈哈%s"%i a=dd() dd=0 for i in a: dd+=1 print(i) if dd>6: break print("*************************************") # 表示生成了两个迭代器 而生成器函数可以作用于一个迭代器 ll=[1,2,3,4,5,6] for i in ll: if i==3: break print(i) print("*************************************") for i in ll: print(i)
def ff(): for i in range(100): yield "生成%s"%i f=ff() f1=ff() print(f.__next__()) print(f.__next__()) print(f.__next__()) print(f.__next__()) print(f.__next__()) print("***********") print(f1.__next__()) print(f1.__next__()) # 说明了自己走自己的 相当于两个迭代器 # 生成0 # 生成1 # 生成2 # 生成3 # 生成4 # *********** # 生成0 # 生成1
def aa(): print(1) yield "a" dd=aa() # print(list(dd)) 数据类型强制转换 也可以取值 但是太占内存了 print(dd) # 生成器函数 :执行之后会得到一个生成器作为返回值 # generator 生成器 print(dd.__next__()) # <generator object aa at 0x000001CF75392EB8> # 1 # a
def bb(): print("aaaaa") yield "我是aaaa" print("bbbbb") yield "我是bbbb" yield "我是ccc" print(bb()) cc=bb() print(cc) print(cc.__next__()) # aaaaa # 我是aaaa print(cc.__next__()) # bbbbb # 我是bbbb
def bb(): print("aaaaa") yield "我是aaaa" print("bbbbb") yield "我是bbbb" yield "我是ccc" cc=bb() # print(cc.__next__()) # aaaaa 我是aaaa # print(cc.__next__()) # bbbbb 我是bbbb # print(cc.__next__()) # 我是ccc print("**************************************") print(cc,"这是迭代器哈哈哈哈哈") for i in cc: print(i,"for循环") # aaaaa # 我是aaaa for循环 # bbbbb # 我是bbbb for循环 # 我是ccc for循环
# 边生成数据边处理数据 def ff(): for i in range(100): yield "生成%s"%i f=ff() for i in f: print(i) # 边生成数据边处理数据 def ff(): for i in range(100): yield "生成%s"%i f=ff() cont=0 for i in f: cont+=1 if cont>50: break print(i)
def aa(): print(111) yield "我是111" print(222) yield "我是222" yield "我是垃圾" b=aa() # print(b) print(b.__next__()) # 111 我是111 print(b.__next__()) # 222 我是222 print(b.__next__()) # 我是垃圾
1. send方法() 以在获取下一个值时 可以给上一个yield的位置传递参数
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。def aa(): print(111) yield "我是111" print(222) yield "我是222" yield "我是垃圾" b=aa() # print(b) print(b.__next__()) # 111 我是111 print(b.send(None)) # send的效果和next一样 # 222 我是222
# send获取下一个值的效果和next一样的 # 但是send 可以在获取下一个值时 可以给上一个yield的位置传递参数 # send 注意使用 # 第一次使用生成器的时候 是必须用next获取下一个值 # 最后一个yield不能接受外部的值 def aa(): print(111) cont=yield "我是111" print("我是",cont) print(22222) yield "我是333333" b=aa() # print(b) print(b.__next__()) # 111 # 我是111 print(b.send("hello")) # send的效果和next一样 但是可以传参数 # 我是 hello # 22222 # 我是333333

# 获取移动平均值 # 10 20 30 10 # # avg=sum/count def bb(): sum=0 count=0 avg=0 while True: num=yield avg sum+=num count+=1 avg=sum/count c=bb() c.__next__() av=c.send(20) av=c.send(30) av=c.send(10) print(av)生成器 获取平均值案例
2. yield from
def gen(): a='123456' b='abcdef' yield from a yield from b a=gen() for i in a: print(i)

# 监听文件用户文件输入 aa=r"D:\aaaa育\01day\生成器函数\aa.txt" # strip() 方法用于移除字符串头尾指定的字符 def cc(bb): with open(bb,encoding="utf-8")as f1: while True: li=f1.readline() if li.strip(): #去掉回车空格 yield li.strip() dd=cc(aa) for i in dd: print("****",i)生成器函数文件监听案例
def bb(): for i in range(20): yield "生成%d"%i aa=bb() cc=0 for i in aa: cc+=1 if cc>6: break print(i) # 生成0 # 生成1 # 生成2 # 生成3 # 生成4 # 生成5
# with open('25生成器人口普查','r',encoding='utf-8') as f: # 利用生成器取人口数 def g(): with open('./25生成器人口普查.py','r',encoding='utf-8') as f: for i in f: yield i a=g() c1=a.__next__() c2=a.__next__() print(c1) print(c2) # {"name":"上海","renkou":7700} # {"name":"湖北","renkou":1400} print("*******************# 利用生成器取人口数***************************") def A(): with open('./25生成器人口普查.py','r',encoding='utf-8') as f: for i in f: yield i S=A() k=eval(S.__next__()) # 转换成字典dict print(k) print(type(k)) # {'name': '上海', 'renkou': 7700} # <class 'dict'> print(k['renkou']) # 7700 # 取出所以人口数 def Q(): with open('./25生成器人口普查.py','r',encoding='utf-8') as f: for i in f: yield i n=Q() for h in n: D=eval(h) print(D['renkou']) # 7700 # 7700 # 1400 # 500 # 600 # 30000 # 222200 print("*********************1111****************************") # 求出总人数 def ff(): with open('./25生成器人口普查.py','r',encoding='utf-8') as f: for i in f: yield i v=ff() res=0 for h in v: D=eval(h) # print(D['renkou']) res+=D['renkou'] print(res) # 262400 # 求出总人数 def ff(): with open('./25生成器人口普查.py','r',encoding='utf-8') as f: for i in f: yield i v=ff() x=sum(eval(i)['renkou'] for i in v) print(x) # 描述 # sum() 方法对系列进行求和计算。 # 语法 # 以下是 sum() 方法的语法: # sum(iterable[, start]) # 参数 # iterable -- 可迭代对象,如:列表、元组、集合。 # start -- 指定相加的参数,如果没有设置这个值,默认为0。
# 模拟生产包子吃包子 # 注意:这样生产消费太消耗时间了 不严谨 # 01 生产包子 def aa (): ret=[] for x in range(20): ret.append('包子%s'%x) return ret # 02 造人来一个吃一个 def bb(res): for index,baozi in enumerate(res): print('第%s个人,吃了%s'%(index,baozi)) res=aa() bb(res) """第0个人,吃了包子0 第1个人,吃了包子1 第2个人,吃了包子2 第3个人,吃了包子3 第4个人,吃了包子4 第5个人,吃了包子5 ........"""
# 母鸡下载案例 (生成器) # 这种案例 :生成器 占空间大 效率低 # # 这个表示鸡蛋全部下出来了 def xiadan(): ret=[] for i in range(8): ret.append('鸡蛋%s'%i) return ret aa=xiadan() print(aa) # ['鸡蛋0', '鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4', '鸡蛋5', '鸡蛋6', '鸡蛋7'] # 这个表示需要一个鸡蛋就下一个 def vv(): for i in range (8): yield '鸡蛋%s'%i aa=vv() BB1=aa.__next__() BB2=aa.__next__() BB3=aa.__next__() print(BB1) # 鸡蛋0 print(BB2) # 鸡蛋1 print(BB3) # 鸡蛋2

更多精彩