學點簡單的Python之Python生成器
??大家好,我叫亓官劼(qí guān jié ),在CSDN中記錄學習的點滴歷程,時光荏苒,未來可期,加油~博主目前僅在CSDN中寫博客,唯一博客更新的地址為:亓官劼的博客 ,同時正在嘗試在B站中做一些內容分享,B站主頁為: 亓官劼的B站主頁
本文原創為亓官劼,請大家支持原創,部分平臺一直在惡意盜取博主的文章!!!
若需聯系博主,可以聯系本人微信:qiguanjie2015
什么是生成器?生成器能夠做什么
在Python中,使用了yield的函式被稱為生成器,生成器回傳的是一個迭代器的函式,只能用于迭代操作,在呼叫生成器運行的程序中,每次遇到 yield 時函式會暫停并保存當前所有的運行資訊,回傳 yield 的值, 并在下一次執行 next() 方法時從當前位置繼續運行,
生成器常用場景:例如我們需要生成一個有規律向前推進的串列,或者一個1-1億的串列等等,當我們串列中元素數量十分大時,記憶體會爆堆疊,但是如何我們元素間是有規律的,則我們可以利用生成器來解決這個問題,
例如一個簡單是生成器應用實體,利用生成器輸出1-1億的數,
list = (i for i in range(1,100000000))
for item in list:
print(item)
注意這里使用的是()而不是串列的[],如果使用串列,記憶體將會爆堆疊,程式直接卡死,各位小伙伴有興趣的話可以自己嘗試一下哦!
如何創建一個生成器?如何使用生成器?
那生成器只能生成這樣連續的簡單數列嗎?當然不是!我們可以撰寫自己的生成器函式,例如我們撰寫一個斐波那契數列的生成器,
# 生成器函式 - 斐波那契數列
def fibonacci(n):
# a為第一個數,b為第二個數,counter為當前是第幾個,迭代向前推進
a, b, counter = 0, 1, 0
while True:
if counter > n:
return
yield a
a, b = b, a + b
counter += 1
# fib 是一個迭代器,由生成器回傳生成
fib = fibonacci(10)
for item in fib:
print(item)
輸出為:
0
1
1
2
3
5
8
13
21
34
55
這里我們每次回傳一個fibonacci數列的值,每次回傳的值即通過yield回傳的值,回傳之后生成器中的狀態保持不變,等待下一次呼叫,當下一次呼叫來時,繼續運行直到通過yield回傳下一個值,以此回圈,生成器不是將所有數保存在數列中,而是一個迭代器,每次回傳時向前迭代,
next()和send()函式
我們可以利用next( )函式來獲取迭代器的下一個值,例如下面這個例子:
def gen():
yield 1
yield 2
yield 3
yield 4
# a是由生成器gen生成的一個迭代器
a = gen()
print(next(a))# 輸出a中下一個值
print(next(a))# 輸出a中下一個值
print(next(a))# 輸出a中下一個值
print(next(a))# 輸出a中下一個值
輸出結果為:
1
2
3
4
生成器即是迭代器也是可迭代物件,即我們可以通過next來依次獲取迭代器中的值,同時也可以通過之前例子中的迭代器直接獲取,
當前例子中我們迭代器中只有四個值,那么當我們獲取四個值之后再次呼叫next(a)時,便會拋出StopIteration例外,即當前迭代器沒法繼續向前迭代,
同時,我們也可以使用send()函式來獲取下一個值,但是與next()函式不同的是,send()函式需要一個引數,將這個引數發送到yield運算式的值,例如下面這個例子:
def gen():
temp = yield 1
print(temp)
temp = yield 2
print(temp)
temp = yield 3
print(temp)
temp = yield 4
print(temp)
# a是由生成器gen生成的一個迭代器
a = gen()
print(next(a))# 輸出a中下一個值
print(next(a))# 輸出a中下一個值
print(next(a))# 輸出a中下一個值
print(next(a))# 輸出a中下一個值
這時我們的輸出為:
1
None
2
None
3
None
4
這里與我們上面例子不同的是,我們每次yield回傳后,將這個yield 1的值作為運算式賦值給temp,當我們直接使用next()獲取時,這個運算式的值為None,同時我們發現只輸出了三個None,這也驗證了我們之前說的,每次呼叫下一個值后,我們會停留在yield的位置,保存所有狀態,直到下一次呼叫才會繼續向下走,
我們通過send()函式來獲取下一個值時,我們在send()函式中傳的引數將會作為yield 1運算式的值賦值給temp,例如下面的例子,
def gen():
temp = yield 1
print(temp)
temp = yield 2
print(temp)
temp = yield 3
print(temp)
temp = yield 4
print(temp)
# a是由生成器gen生成的一個迭代器
a = gen()
print(a.send(None))# 輸出a中下一個值,第一次執行生成器代碼的時候,send函式必須要傳遞None進去,否則會報錯
print(a.send('qiguanjie1'))# 輸出a中下一個值,并傳入引數qiguanjie1給yield運算式
print(a.send('qiguanjie2'))# 輸出a中下一個值,并傳入引數qiguanjie2給yield運算式
print(a.send('qiguanjie3'))# 輸出a中下一個值,并傳入引數qiguanjie3給yield運算式
輸出為:
1
qiguanjie1
2
qiguanjie2
3
qiguanjie3
4
如果我們要使用send()來呼叫下一個值但我們不需要發送訊息時,我們可以傳遞一個None進去,即a.send(None)
好了,今天的學點簡單的Python之Python生成器篇就到這里了,我們下次再見!如果這篇文章對您有幫助的話,可以點贊關注博主一下,給博主一些鼓勵,哈哈~
CSDN認證博客專家
Python
全堆疊
資料結構與演算法
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/246565.html
標籤:python
