一.生成器
什么是生成器,生成器的实质就是迭代器
在python中有三种方式来获取生成器:
1.通过生成器函数
2.通过各种推导式来实现生成器
3.通过数据的转换也可以获取生成器
1 def func()
2 print("111")
3 yield 222
4 ret = func()
5 print(ret)
6
7 结果:
8 <generator object func at 0x10567ff68>
send方法和__next__()
send和__next__()一样都可以让生成器执行到下一个yield.
1 def eat(): 2 print("我吃什么啊") 3 a = yield "馒头" 4 print("a=",a) 5 b = yield "大饼" 6 print("b=",b) 7 c = yield "韭菜盒子" 8 print("c=",c) 9 yield "GAME OVER" 10 gen = eat() # 获取生成器器 11 ret1 = gen.__next__() 12 print(ret1) 13 ret2 = gen.send("胡辣汤") 14 print(ret2) 15 ret3 = gen.send("狗粮") 16 print(ret3) 17 ret4 = gen.send("猫粮") 18 print(ret4)
send和__next__() 的区别:
1.send和next()都是让生成器向下走一次
2.send可以让上一个yield的位置传递值,不能给最后一个yield发送值,在第一次执行生成器代码的时候不能用send()
生成器可以使用for循环来获取内部元素:
1 def func(): 2 print(111) 3 yield 222 4 print(333) 5 yield 444 6 print(555) 7 yield 666 8 gen = func() 9 for i in gen: 10 print(i) 11 12 13 结果: 14 111 15 222 16 333 17 444 18 555 19 666
二.列表推导式,生成器表达式以及其他推导式
首先给出如下代码
1 lst = [] 2 for i in range(1,15) 3 lst.append(i) 4 print(lst)
替换成列表推导式:
1 lst = [i for i in range(1,15)] 2 print(lst)
语法:
[结果 for 变量 in 可迭代对象 if 条件]
列表推导式可对结果进行筛选:
1 lst = [i for i in range(1,15) if i%2 ==0] 2 print(lst)
生成器表达式与列表推导式的语法是一致的,只是把[]替换成了()
1 gen = (i for i in range(1,15)) 2 print(gen) 3 4 结果: 5 <generator object <genexpr> at 0x106768f10>
打印的结果是一个生成器,我们可以通过for循环来循环这个生成器:
1 gen = (i for i in range(10)) 2 for i in gen: 3 print(i)
生成器表达式同样可以进行筛选:
1 #获取1-100内能被3整除的数 2 gen = (i for i in range(1,100) if i %3 == 0) 3 4 for num in gen: 5 print(num)
生成器表达式和列表推导式的区别:
1.列表推导式比较耗内存,一次性加载,生成器表达式几乎不占用内存,使用的时候采配合使用内存
2.得到的值不一样,列表推导式得到的是一个列表,生成器表达式获取的是一个生成器.
生成器的惰性机制:
1 def func() 2 print("111") 3 yield 222 4 5 g = func() #生成器g 6 g1 = (i for i in g) #生成器g1,但是生成器的数据来源于g 7 g2 = (i for i in g1) #生成器g2,来源于g1 8 9 print(list(g)) #获取g中的数据,这时func()才会被执行,打印,获取到222,g完毕 10 print(list(g1)) #获取g1中的数据,g1的数据来源于g,但是g已经取完,g1也没有数据 11 print(list(g2)) #与g1同理
字典推导式:
1 # 把字典中的key和value互换 2 dic = {'a': 1, 'b': '2'} 3 new_dic = {dic[key]: key for key in dic} 4 print(new_dic) 5 6 # 在以下list中. 从lst1中获取的数据和lst2中相对应的位置的数据组成一个新字典 7 lst1 = ['jay', 'jj', 'sylar'] 8 lst2 = ['周杰伦', '林俊杰', '邱彦涛'] 9 dic = {lst1[i]: lst2[i] for i in range(len(lst1))} 10 print(dic)
集合推导式:
集合推导式可以帮我们直接生成一个集合,集合的特点:无序,不重复,所以集合推导式自带去重功能
1 lst = [1, -1, 8, -8, 12] 2 # 绝对值去重 3 s = {abs(i) for i in lst} 4 print(s)
生成器表达式:
1 def add(a, b): 2 return a + b 3 4 def test(): 5 for r_i in range(4): 6 yield r_i 7 g = test() 8 9 for n in [2, 10]: 10 g = (add(n, i) for i in g) 11 12 print(list(g))
结果:
[20,21,22,23]
生成器的惰性机制