經過列表生成式咱們能夠方便的生成列表。可是在有的時候,咱們須要生成的列表很是長,而咱們的計算機的內存是有限的。在操做列表的時候,咱們每每只是操做了列表的一部分區域的數據。python
例如咱們須要生成這麼一個列表,列表中除了第1個和第2個數字外,其他數字都是前兩個數之和。算法
1,2,3,5,8,13...
若是這個數組只有幾千個或者幾萬個數字的時候,咱們或許還能將它們都生成存在內存中。可是咱們若是須要連續計算幾千萬個數字的時候,我再按上面的思路來就不大現實了。數組
認真思考一下上面的數列,咱們在遍歷的時候,其實只要知道前兩個數字的數值,咱們就能源源不斷地計算出下一個數值是多少。函數
Python其實已經給咱們提供了現有的工具讓咱們生成數列。與以前的生成式不一樣,生成器(Generators)在定義的時候並非直接在內存中生成數列,而是定義一個生成數列的算法。工具
定義列表生成器有兩種方式,一種是算式列表生成器(我起的名字),一種經過yield
關鍵詞。指針
算式列表生成器雨列表生成式相似,但[]
須要換成()
。code
my_gernerator = (x*x for x in range(1,101))
咱們能夠調用generator object的next()函數讓指針下移。例如對象
print my_generator.next() #輸出 1 print my_generator.next() #輸出 4 print my_generator.next() #輸出 9
每調用一次next()
,計算出一個值,並記憶迭代到何處了。當迭代到最後一個元素後再調用next()
,python則會拋出StopIteration
錯誤。咱們能夠捕獲這個錯誤來處理迭代終止。next()
這種手動調用的運用較少。內存
咱們能夠利用collections.Iterable
來判斷generator object
是不是一個Iterable
對象。ci
from collections import Iterable g = (x**3 for x in range(1,101)) print isinstance(g, Iterable) #輸出True
所以咱們能夠用for
迭代generator object
。
for item in g: print item
yield
的函數定義列表生成器在定義一個比較複雜的列表生成器的時候,上述算式型的列表生成器已經不能知足咱們的需求了。咱們能夠用一個包含yield
關鍵字的函數來定義一個列表生成器。
例如咱們來實現一下文章開頭生成一個「每一個數字都是前兩個數字之和」的數列。
def fibonacci(max): n,a,b = 0,1,2 while n<max: yield b #-----> Generator迭代到該處時,即產生一個數。並暫停在此處,等待下一次迭代,又從該處開始,又直到遇到下一個yield..不斷反覆,直到程序結束。 a,b = b,a+b n = n+1
此時,fibonacci
再也不是一個普通函數,而是一個generator object
。
咱們一般用for
循環來迭代generator
對象。
for n in fibonacci(10): print n