生成器的實質就是迭代器
生成器表達式:app
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:函數
如何把一行代碼換成兩行:spa
在你想換行的地方後面加\,而後接着寫就好了code