Day14 of learning python--生成器的进阶及各种推导式
1.生成器概念
判断是否是可迭代的,print('__iter__' in dir(数据类型))
生成器的表现形式:生成器函数,生成器表达式
生成器特点呢:调用函数之后函数不执行,返回一个生成器,调用next方法的时候会激活生成器函数执行代码,直到遇到第一个yield。每一次执行g.__next__()就是从生成器中取值,预示着生成器函数中的代码继续执行
for循环就是生成一个迭代器。从生成器中取值的几个方法:next,for,数据类型的强制转换(占用内存)
2.生成器send()函数的使用
send()函数的作用:send的获取下一个值效果和next基本一致,只是在获取下一个值得时候,给上一个值的位置传递一个数据
使用send的注意事项:第一次使用生成器的时候,是用next获取下一个值;最后一个yield不能接受外部的值,否则会报错StopIteration
1 def generator(): 2 print(123) 3 content = yield 1 4 print('!!!',content) 5 print(456) 6 yield 2 7 print(789) 8 9 g = generator() 10 ret = g.__next__() 11 print('***',ret) 12 ret = g.send('hello') #send的效果和next一样,不能传空的,可以传None 13 print('***',ret)
例子:获取移动平均值,(预激生成器的装饰器的例子)
1 def init(func): # func = avgrage 2 def inner(*args,**kwargs): 3 g = func(*args,**kwargs) # g = avgrage() 返回生成器地址 4 g.__next__() #触发生成器函数的执行 5 return g 6 return inner 7 8 @init # avgrage = init(avgrage) = inner 9 def avgrage(): 10 sum = 0 11 count = 0 12 avg = 0 13 while True: 14 num = yield avg 15 sum += num 16 count += 1 17 avg = sum / count 18 19 avg_g = avgrage() # --> inner() 20 avg1 = avg_g.send(10) 21 avg1 = avg_g.send(20) 22 print(avg1)
结果:
123
*** 1
!!! hello
456
*** 2
3.生成器from的使用
例子,从a,b字符串中逐个获取元素
1 def generator(): 2 a = 'abcde' 3 b = '12345' 4 for i in a: # yield from a 5 yield i 6 for i in b: # yield from b 7 yield i 8 9 g = generator() 10 for i in g: 11 print(i)
4.各种推导式
[每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型] 遍历功能
[满足条件的元素相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件] 筛选功能
1)生成器表达式,与列表推导式相比较,括号不一样,返回值不一样,几乎不占用内存
1 g = (i for i in range(10)) # 此处还没有执行for循环的内容 2 print(g) 3 for i in g: 4 print(i)
2)列表推导式
1 egg_list = ['鸡蛋%s' %i for i in range(10)] #列表推导式 2 print(egg_list)
3)字典推导式
例子:将一个字典的key和value对调
1 mcase = {'a':10,'b':34} 2 mcase_frequency = {mcase[k]: k for k in mcase} 3 print(mcase_frequency)
结果:{10: 'a', 34: 'b'}
4)集合推导式(去除重复的数据)
1 square = {x*x for x in [1,-1,2]} 2 print(square)
结果:{1, 4}
练习例子:
1 # 30以内所有能被3整除的数 2 ret = [i for i in range(30) if i%3 == 0] #完整的列表推导式 3 print(ret) 4 结果:[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
1 # 30以内所有能被3整除的数的平方 2 ret = [i*i for i in range(30) if i%3 ==0] 3 print(ret) 4 结果:[0, 9, 36, 81, 144, 225, 324, 441, 576, 729]
1 # 找嵌套列表中含有两个e的名字 2 names = [['tom','jefferson','son'],['html','keel']] 3 ret = [name for lst in names for name in lst if name.count('e')==2] 4 print(ret) 5 结果:['jefferson', 'keel']
1 # 合并大小写对应的value值,将K统一成小写 2 mcase = {'a':10,'b':34,'A':7,'Z':3} 3 mcase_frequency = {k.lower():mcase.get(k.lower(),0)+mcase.get(k.upper(),0) for k in mcase.keys()} 4 print(mcase_frequency) # .get(*),没有找到就是None,所有添加一个参数0,以免不能相加 5 结果:{'a': 17, 'b': 34, 'z': 3}
浙公网安备 33010602011771号