生成器进阶
1、send
def gen():
print(111)
cont=yield 123 #给yield赋值cont
print('====',cont) #执行赋值
print(222)
yield 456
yield 789
g = gen() #生成器函数执行之后返回生成器函数
ret=g.__next__() #执行next得到返回值赋给ret
print(ret)
ret=g.send(99999999999) #用send给yield传值
print(ret) #send的作用效果和next一样
ret=g.send()
print(ret)
send的使用注意事项:
1、send获取下一个值的效果和next基本一样,只是在获取下一个值的时候,给上一个yield的位置传递一个数据
2、使用send的注意事项:
1、第一次使用生成器的时候,是用next获取下一个值
2、最后一个yield不能接收外部的值
2、例子:
1、计算移动平均值
def avrage(): sum=0 count=0 avg=0 while True: num = yield avg #进入循环,为上一个yield赋值,返回平均值 sum+=num count+=1 avg=sum/count avg_a = avrage() ret = avg_a.__next__() #第一次使用生成器,先用next获取下一个值 print(ret) #ret接收yield返回值 ret=avg_a.send(10) print(ret) ret=avg_a.send(15) print(ret) ret=avg_a.send(30) print(ret)
2、预激生成器的装饰器
def init(func): #装饰器 def inner(*args,**kwargs): g = func(*args,**kwargs) #g=avrage() g.__next__() return g return inner @init def avrage(): sum=0 count=0 avg=0 while True: num=yield avg sum+=num count+=1 avg=sum/count avg1=avrage() #avg1=inner ret=avg1.send(10) print(ret) ret=avg1.send(20) print(ret) ret=avg1.send(30) print(ret)
3、yield from
a=[1,2,3,4,5] for i in a: yield i #可以用yield from写成 a= [1,2,3,4,5] yield from a
for循环读取数据的时候是一个一个的读取,所以用 yield from 读取的时候也是一个一个的读取
4、列表生成器
lis=['鸡蛋%s'%i for i in range(20)] #这个就叫列表推导式 print(lis)
g=(i*i for i in range(10)) #这个叫生成器表达式 for i in g: print(i)
列表推导式与生成器表达式的区别:
1、括号不一样
2、列表推导式是一次性生成,生成器表达式只是生成一个生成器(就像是列表推导式生成一堆鸡蛋,而生成器表达式是生成了一直老母鸡,在需要的时候进行for循环或者next再生成鸡蛋),生成器表达式几乎不占内存。
# 老母鸡=('鸡蛋%s'%i for i in range(10)) #生成器表达式 # print(老母鸡) # for 蛋 in 老母鸡: # print(蛋)
5、各种推导式
[ 每一个元素和元素相关的操作 for 元素 in 可迭代数据类型 ] #遍历之后挨个处理
或者 (带筛选功能)
[ 满足条件的元素相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件 ]
lis=[i for i in range(30) if i % 3 ==0] print(lis) #30以内能被3整除的数
#例:找到嵌套列表中名字含有两个‘e’的所有名字
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] lis=[name for name1 in names for name in name1 if name.count('e')==2] print(lis)
执行结果:
例一:将一个字典的key和value对调 {10:'a' , 34:'b'} mcase_frequency = {mcase[k]: k for k in mcase} print(mcase_frequency) 例二:合并大小写对应的value值,将k统一成小写 mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3} {'a':10+7,'b':34,'z':3} mcase_frequency = {k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase} print(mcase_frequency)
#集合推导式,自带结果去重功能 # squared = {x**2 for x in [1, -1, 2]} # print(squared)