因爲生成器其實是一種特殊的迭代器。不過這種迭代器更加優雅。它不需要再像上面的類一樣寫__iter__()
和__next__()
方法了,只需要一個yiled
關鍵字。 生成器一定是迭代器(反之不成立),因此任何生成器也是以一種懶加載的模式生成值。
第一類:生成器函數:還是使用 def 定義函數,但是,使用yield而不是return語句返回結果。yield語句一次返回一個結果,在每個結果中間,掛起函數的狀態,以便下次從它離開的地方繼續執行。
如下案例加以說明:
def fib(n):
a, b = 0, 1
while b <= n:
yield b
a, b = b, a+b
f = fib(10)
for item in f:
print(item)
第二類:生成器表達式:類似於列表推導,只不過是把一對大括號[]變換爲一對小括號()。但是,生成器表達式是按需產生一個生成器結果對象,要想拿到每一個元素,就需要循環遍歷。
如下案例加以說明:
# 一個列表
xiaoke=[2,3,4,5]
# 生成器generator,類似於list,但是是把[]改爲()
gen=(a for a in xiaoke)
for i in gen:
print(i)
#結果是:
2
3
4
5
摘一段<python核心編程>的內容:
生成器的另外一個方面甚至更加強力----協同程序的概念。協同程序是可以運行的獨立函數調用,可以暫停或者掛起,並從程序離開的地方繼續或者重新開始。在有調用者和(被調用的)協同程序也有通信。舉例來說,當協同程序暫停時,我們仍可以從其中獲得一箇中間的返回值,當調用回到程序中時,能夠傳入額外或者改變了的參數,但是仍然能夠從我們上次離開的地方繼續,並且所有狀態完整。掛起返回出中間值並多次繼續的協同程序被稱爲生成器,那就是python的生成真正在做的事情。這些提升讓生成器更加接近一個完全的協同程序,因爲允許值(和異常)能傳回到一個繼續的函數中,同樣的,當等待一個生成器的時候,生成器現在能返回控制,在調用的生成器能掛起(返回一個結果)之前,調用生成器返回一個結果而不是阻塞的等待那個結果返回。