python生成器函数_【python】生成器和生成器函数
1、生成器函數:
普通函數:
def?func():
print("周杰倫")
return?"昆凌"
func()?#執行func()函數,"周杰倫"
print(func())??#執行結果:昆凌
生成器函數:
def?func():
print("周杰倫")
yield?"昆凌"??#?函數中包含了yield,?當前這個函數就不再是普通的函數了.?是生成器函數
func()?#通過func()函數生成一個生成器,非執行,沒結果
print(func())?#打印的是該生成器函數所在的內存地址
#return?和yield的區別:
return:?執行到return時函數結束執行
yield:函數分段執行,從(當前yield到下一個yield]的內容
舉例:
def?func():
print("周杰倫")
yield?"昆凌"
print("王力宏")
yield?"李云迪"
#print("大家好才是真的好")? #最后一個yield后不要寫東西,因為__next__()找不到下一個yield時會報錯StopIteration
g=func()?#生成一個生成器
print(g.__next__())?#周杰倫?昆凌
print(g.__next__())?#王力宏?李云迪
2、send()
#__next__()和send()區別:
__next__()?可以讓生成器向下執行一次;
send()?也可以讓生成器向下執行一次,?給上一個yield傳一個值,?第一個和最后一個yield不需要傳值(最后一個值可以傳進去但會報錯)。
舉例1:
def?eat():
print("我吃什么啊")
a?=??yield??"饅頭"
print("a=",a)
b?=??yield??"大餅"
print("b=",b)
c?=??yield??"韭菜盒子"
print("c=",c)
yield??"GAME?OVER"
gen?=?eat()? ? ?#?獲取生成器
ret1?=?gen.?__next__?()
print(ret1)
ret2?=?gen.send("胡辣湯")
print(ret2)
ret3?=?gen.send("狗糧")
print(ret3)
ret4?=?gen.send("貓糧")
print(ret4)
執行結果:
我吃什么啊
饅頭--------------第一次__next__()獲取的內容
a= 胡辣湯----第一次send賦值,并打印
大餅-------第一次send獲取的內容
b= 狗糧---第二次send賦值
韭菜盒子---第二次send獲取的內容
c= 貓糧
GAME OVER
舉例2:
def?func():
print('0')
yield?1
print('2')
yield?3
yield?4
g1?=?func()
lst?=?list(g1)??#把生成器轉換成列表
print(lst)
執行結果:
0
2
[1, 3, 4]
3、列表推倒式
語法:[最終結果?for?變量?in?可迭代對象?if?條件]
lst?=?[i?for?i?in?range(1,101)?if?i%2==0]
print(lst)
4、生成器表達式
#生成器表達式和列表推倒式基本是一樣的,只是把[]換成()
語法:(最終結果?for?變量?in?可迭代對象?if?條件)
g?=?(i?for?i?in?range(10))
print(g)?#打印的是通過表達式生成的生成器所在的內存地址
print(g.__next__())?#獲取的第一個元素是0
print(list(g))?#獲取的是列表?[0,1,2,3,4,5,6,7,8,9]
5、其他推倒式
5.1 字典推倒式:
語法:[結果(key:value)?for?變量?in?可迭代對象?if 篩選]
#把字典中的key:value互換?.{"b":"a",?"d":"c"}
dic?=?{"a":"b",?"c":"d"}
new_dic?=?{dic[key]:key?for?key?in?dic}
print(new_dic)
5.2?集合推倒式:
語法:{結果(key)?for?變量?in?可迭代對象?if 篩選}
lst?=?["馬化騰",?"馬化騰",?"王建忠",?"張建忠",?"張雪峰",?"張雪峰"]
s?=?{i?for?i?in?lst}????#?集合推倒式,無序且不重復,自動去重
print(s)
注:沒有元組推倒式(因為元組不可變,小括號括起來的是生成器表達式)
總結:
1、生成器的本質就是迭代器
2、生成器3種生成方法:
1)通過生成器函數
2)通過生成器表達式
3)通過數據轉換
3、生成器函數被執行,如func()是拿到一個生成器函數,不是獲取里面的內容
4、生成器取值:
1)__next__()
2)send()
3)for循環
4)list(g)
5、return?和yield的區別:
return:?執行到return時函數結束執行
yield:函數分段執行,從(當前yield到下一個yield]的內容
6、生成器惰性機制應用
舉例1:
def?func():
print(111)
yield??222
g?=?func()?#生成器g
g1?=?(i??for?i?in??g)?#生成器g1,但數據來源g
g2?=?(i??for?i?in??g1)#生成器g2,但數據來源g1
print(list(g))?#獲取生成器g數據,此時func()才會被執行,打印111,獲取到222
print(list(g1))#獲取g1數據,來源g,但g數據已被取完,所以返回是空
print(list(g2))#同g1
執行結果:
111
[222]
[]
[]
舉例2:若把print(list(g))注釋了,得到的結果怎樣?
def?func():
print(111)
yield??222
g?=?func()?#生成器g
g1?=?(i??for?i?in??g)?#生成器g1,但數據來源g
g2?=?(i??for?i?in??g1)#生成器g2,但數據來源g1
#print(list(g))
print(list(g1))
print(list(g2))
執行結果:
111
[222]
[]
舉例3:
def?add(a,b):
return?a?+?b
def?test():
for?i?in?range(4):
yield?i
g?=?test()?#0,1,2,3,
for?n?in?[2,10]:?#n?取值2,10?表示共循環2次
g=(add(n,i)?for?i?in?g)
print(list(g))
#list(g)時才會執行,生成器惰性特質
#g=(add(n,i)?for?i?in?g)?循環2次,相當于最后g=(add(n,i)?for?i?in?(add(n,i)?for?i?in?g))
#g=(add(n,i)?for?i?in?(add(n,i)?for?i?in?(0,1,2,3)))
#生成器不到最后不執行,最后一次n=10,那么g=(add(10,i)?for?i?in?(10,11,12,13))
#g=[20,21,22,23]
總結
以上是生活随笔為你收集整理的python生成器函数_【python】生成器和生成器函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 需要使用新应用以打开此steam链接_s
- 下一篇: mos管电路_【鼎阳硬件智库原创︱电源】