Python強大的引進-生成器。這就是我們今天要學習的這一章內容。
定義:
在Python中,這種一邊循環一邊計算的機制,稱為生成器(Generator)。換句更簡單的話來理解:任何包含yield語句的函數稱為為生成器。
好處:
通過列表生成式,我們可以直接創建一個列表。但是,受到內存限制,列表容量肯定是有限的。而且,創建一個包含100萬個元素的列表,不僅占用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那后面絕大多數元素占用的空間都白白浪費了。
所以,如果列表元素可以按照某種算法推算出來,那我們是否可以在循環的過程中不斷推算出后續的元素呢?這樣就不必創建完整的list,從而節省大量的空間。
工作原理:
它是在for循環的過程中不斷計算出下一個元素,并在適當的條件結束for循環。對于函數改成的generator來說,遇到return語句或者執行到函數體最后一行語句,就是結束generator的指令,for循環隨之結束。
如何創建:
1. 只要把一個列表生成式的【】換成()就可以。
2. 上圖的例子是用yield來說明一下怎么創建生成器。
打開百度App,看更多圖片
其實與創建函數類似: 區別是,創建函數是return返回值。創建生長期是yield產生多個值,每次產生一個,函數就會凍結,等在那里等待被再次激活。等激活后從停止的那點開始執行。
生成器種類:
A. 循環生成器。與列表推導式類似。只不過一個是返回列表一個是返回生成器(不會立刻循環)。請看下面例子來說明區別。
>>> L = [x * x for x in range(10)]
>>> L [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g <generator object <genexpr> at 0x104feab40>
>>> for n in g:
print n
B. 遞歸生成器。
C. 通用生成器:
生成器的組成 1. 生成器函數: def定義,包含yield部分。
2. 生成器迭代器:這個函數的返回部分。
生成器方法
send
類似于next,在比不過需要一個發送的參數。
def repeater(value):
while True:
new=(yield value)
if new is not None:value=new
>>> r=repeater(42)
>>> r.next()
42
>>> r.send('hello world')
'hello world'
throw方法:
使用異常類型調用,還有可選的值以及回溯對象,用于生成器內引發一個異常。(在yield表達式中)
close方法:
調用時不要參數,用于停止生成器。
模擬生成器
當舊版本不能使用時生成器時,需要普通函數模擬生成器。
方式:1. result=[]防御函數體開始處。
2. yield some_expression 用result.append(some_expression)代替。
3.函數末尾添加return result
注:前面的遞歸生成器flatten就可以用普通函數重寫模擬生成器。
案例總結