python中的生成器
一.生成器(generator)
生成器的实质就是迭代器
生成器表达式:
1 def func():
2 print('111')
3 yield 222
三种执行生成器的方式
1.通过g.__next__(),send()来实现生成器
1 def func():
2 print(111)
3 yield 222
4 # yield 112
5 g=func()
6 print(g.__next__())
2.通过各种推导式来实现生成器(for)
1 def func():
2 print(111)
3 yield 222
4 # yield 112
5 g=func()
6 g1=[i for i in func()]
7 print(g1)
3.通过数据的转换也可以实现生成器:list(),tuple()
1 def func():
2 print(111)
3 yield 222
4 # yield 112
5 g=func()
6 # g1=[i for i in func()]
7 print(list(g)) #获得列表
yield和return的区别:
yield是分段执行一个函数,return是直接停止执行函数
1 def func():
2 print('111')
3 yield 222
4 print('333')
5 yield 444
6 gener=func()
7 ret=gener.__next__()#222
8 print(ret)
9 ret2=gener.__next__()#444
10 print(ret2)
11 ret3=gener.__next__()# ret3=gener.__next__() __next__()如果多了会报错
12 StopIteration
13 print(ret3)
生成器省内存的原因:
1 def cloth():
2 lis=[]
3 for i in range(10000):
4 lis.append(i)
5 print(lis)
6 cloth()#c此时lis列表将所有的值全部都拿出来了,所以非常耗内存
1 def cloth():
2 for i in range(10000):
3 yield i
4 gener=cloth()
5 print(gener.__next__())
6 print(gener.__next__())
7 print(gener.__next__())#一次就一个 用多少生成多少
send()方法:
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 gener=eat()
11 ret=gener.__next__()
12 print(ret)
13 ret2=gener.send('胡辣汤')
14 print(ret2)
15 ret3=gener.send('猫粮')
16 print(ret3)
17 ret4=gener.send('大鱼大肉')
18 print(ret4)
send() 给上一个yield传值, 不能再开头(没有上一个yield), 最后一个yield也不可以用send()
send()和__next__()的区别:
send和next都是让生成器向下走一次,但是send可以给上一个yield的位置传值
二.推导式
2.1列表推导式
1 lst=[i for i in range(10) if i%2==0]
2 print(lst)
写法:[结果 for循环 条件]
1 lis=['我是天下第%s美' % i for i in range(1,5) if i%2==1]
2 print(lis)
2.2.字典推导式
1 dic={'第一美':'我','第一帅':'靳文博'}
2 dic_new={value:key for key,value in dic.items()}
3 print(dic_new)
写法同列表推导式
2.3集合推导式
1 lst=[1,1,2,2,3,4,5]
2 set={i for i in lst}
3 print(set) #自带去重复的功能
写法同列表推导式
2.4 生成器表达式
生成器表达式的语法与以上三个推导式的语法基本上是一样的,只是把[]换成()
1 gener=(i for i in range(5))
2 print(gener) #<generator object <genexpr> at 0x000001D161B6CF68> 结果告诉我们这是一个生成器
获取10以内能被3整除的数
1 gener=(i for i in range(10) if i%3==0)
2 for i in gener:
3 print(i)
生成器表达式和列表推导式的区别:
1.列表推导式比较耗内存,一次全加载出来,生成器表达式几乎不耗内存,使用一个出来一个
生成器的惰性机制
1 def func():
2 print('111')
3 yield 222
4 g=func() #获取生成器
5 g1=(i for i in g) #也是生成器
6 g2=(i for i in g1) #也是生成器
7 print(tuple(g))
8 print(list(g1)) #执行的时候源头已经没有数据了,生成器无法后退
9 print(list(g2))
例子
1 def add(a,b):
2 return a+b
3
4 def test():
5 for i in range(4):
6 yield i
7 g=test()
8
9 for n in [2,10]:
10 g=(add(n,i) for i in g) #此时的n不会带值
11
12 print(list(g))#归根结底还是惰性机制,这里只有 list()才会拿值
13 [20, 21, 22, 23]
小知识点1:
如何把一行代码换成两行:
在你想换行的地方后面加\,然后接着写就行了
改变世界,改变自己!