python之路_生成器进阶及相关表达式
一、生成器中的send用法
send可以把一个值作为信号量传递到生成器函数中,然后和__next__方法一样获取生成器中的值;在生成器执行伊始,只能先使用__next__;二者都是终于yield,而send需要始于一个未被返还的yield处,否则传递的数值将无法被接收。
1、求重复累加平均实例
def average(): count=0 toatal=0 average=0 while True: value=yield average toatal+=value count+=1 average=toatal/count g=average() print(g.__next__()) #激活了生成器,返回yield后面的average,为0 print(g.send(10)) #把10传递给yield前的value,继续执行后面的代码,终于yield后面的average,返回10 print(g.send(20)) #把20传递给yield前的value,继续执行后面的代码,终于yield后面的average,返回15 print(g.send(30)) #.......... print(g.send(40)) print(g.send(50))
2、用send传值失败实例
def func(): print(1) yield 2 print(3) value = yield 4 print(5) yield value g = func() print(g.__next__()) #打印出1和返回2,然后在第一个yield处停止等待 print(g.send(88)) #由于第一个yield处没有未被返回的值,故send传值失败,打印出3和返回4,在第二个yield处停止等待 print(g.__next__()) #value无值传入,打印出5后在第3个yield处返回none
3、用next激活生成器计算累加平均值
def init(func): #在调用被装饰生成器函数的时候首先用next激活生成器 def inner(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return inner @init def average(): mount=0 total=0 average=0 while True: value=yield average total+=value average=total/mount g_avg=average() # next(g_avg) 在装饰器中执行了next方法 print(g_avg.send(10)) print(g_avg.send(20)) print(g_avg.send(30))
二、列表表达式和生成器表达式
1、列表表达式
简化代码,返回的必须是一个列表
#普通代码 result=[] for i in [1,2,3] result.append[i*i] print(result) #列表表达式 print([i*i for i in [1,2,3]])
(1)30内能被3整除的数的实例
print([i for i in range(1,31) if i%3==0])
(2)找到嵌套列表中有两个‘e’的名字
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] print([for list in names for name in list if name.count('e')==2])
2、生成器表达式
把列表解析的[]换成()得到的就是生成器表达式;列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存
laomuji=('鸡蛋%s' %i for i in range(10)) #生成器表达式 print(laomuji) #返回生成器地址<generator object <genexpr> at 0x000001E17AF23BA0> print(next(laomuji)) #输出结果为:鸡蛋0 print(laomuji.__next__()) #输出结果为:鸡蛋1 print(next(laomuji)) #输出结果为:鸡蛋2 #next(laomuji)等价于laomuji.__next__()
3、字典推导式
#将字典键与值对调 mcase = {'a': 10, 'b': 34} print({mcase[k]:k for k in mcase})
4、集合推导式
自带去重功能,将列表解析式的[]换成{}得到集合推导式
print({i*i for i in [1,-1,2]}) #结果为{1,4}
三、生成器表达式面试题
生成器表达式得到是一个生成器 ,生成器只有在取值的时候才能返出值。如下实例得到生成器g的存储地址,并不会如愿得到(1,4,9,16)
g=(i**2 for i in [1,2,3,4]) print(g)
面试实例: