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}
posted on 2018-10-11 15:37  smile大豆芽  阅读(149)  评论(0)    收藏  举报