Python生成器笔记
Python中三大器有迭代器,生成器,裝飾器,本文主要講述生成器。主要從生成器的概念,本質,以及yield關鍵字的使用執(zhí)行過程。
本質:生成器是一類特殊的迭代器,使用了yield關鍵字的函數(shù)不再是函數(shù),而是生成器。(使用了yield的函數(shù)就是生成器)
1.yield關鍵字有兩點作用
1.1 yield語句一次返回一個結果,保存當前運行狀態(tài)(斷點),然后暫停執(zhí)行,掛起函數(shù)的狀態(tài),以便下次重它離開的地方繼續(xù)執(zhí)行,即將生成器(函數(shù))掛起
1.2.將yield關鍵字后面表達式的值作為返回值返回,此時可以理解為起到了return的作用
? ?1.2.1 可以使用next()函數(shù)讓生成器從斷點處繼續(xù)執(zhí)行,即喚醒生成器(函數(shù))
1.2.2 Python3中的生成器可以使用return返回最終運行的返回值,而Python2中的生成器不允許使用return返回一個返回值(即可以使用return從生成器中退出,但return后不能有任何表達式)。
2. 優(yōu)點
2.1 使用生成器函數(shù)代碼量更少。
2.2 生成器的好處是延遲計算,一次返回一個結果,不會一次生成所有的結果,這對于大數(shù)據量處理,將會非常有用,即省內存。
3. 生成方法
3.1 生成器表達式【使用與推算算法筆記簡單的】
3.2 生成器函數(shù)【generator非常強大。如果推算的算法比較復雜,用類似列表生成式的 for 循環(huán)無法實現(xiàn)的時候,還可以用函數(shù)來實現(xiàn)】
4.代碼實現(xiàn)
4.1 創(chuàng)建生成器方法1 ,把列表產生式的[]換成(),即生成器表達式。
In [1]: li=[2*x for x in range(6)]In [2]: li Out[2]: [0, 2, 4, 6, 8, 10]In [3]: type(li) Out[3]: listIn [4]: li=(2*x for x in range(6))In [5]: li Out[5]: <generator object <genexpr> at 0x7fef38260780>In [6]: for item in li:...: print(item)...: 0 2 4 6 8 104.2 創(chuàng)建生成器方法2,使用yield關鍵字。
在使用生成器實現(xiàn)的方式中,我們將原本在迭代器__next__方法中實現(xiàn)的基本邏輯放到一個函數(shù)中來實現(xiàn),但是將每次迭代返回數(shù)值的return換成了yield,此時新定義的函數(shù)便不再是函數(shù),而是一個生成器了。必須捕獲StopIteration錯誤,返回值包含在StopIteration的value中。
def fib(num):i = 0;num1, num2 = 0, 1while i < num:yield num1num1, num2 = num2, num1 + num2i += 1return "none"gen_fib = fib(3) # for item in gen_fib: # print(item) print(gen_fib.__next__()) print(gen_fib.__next__()) print(gen_fib.__next__()) try:print(gen_fib.__next__()) except StopIteration as e:print(e.args)print(e.value)# 0 # 1 # 1 # ('none',) # none4.3 使用send()喚醒函數(shù)
我們除了可以使用next()函數(shù)來喚醒生成器繼續(xù)執(zhí)行外,還可以使用send()函數(shù)來喚醒執(zhí)行。使用send()函數(shù)的一個好處是可以在喚醒的同時向斷點處傳入一個附加數(shù)據。
必須首先使用next(f),或者f.__next__()啟動,才可以使用send()函數(shù)。__next__(相當于None)。首先,使用__next__啟動,當Python解釋器遇到y(tǒng)ield關鍵字時,停止往下執(zhí)行,即yield左邊賦值不再執(zhí)行。當再次調用__next__,或者send時,開始執(zhí)行yield左邊賦值操作。temp的值是send的參數(shù)值,和i無關,如果使用的是__next__喚醒,而不是send喚醒,那么temp的值是None。
def fun():i = 0while i < 5:temp = yield iprint("temp:", temp)i += 1f = fun() f.__next__() f.__next__() f.send("我是send") # 結果 # temp: None # temp: 我是send?
轉載于:https://www.cnblogs.com/greatfish/p/5844113.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結
以上是生活随笔為你收集整理的Python生成器笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到和男人亲热是什么预兆
- 下一篇: 梦到自己要开刀怎么回事