python 學習筆記-列表生成器

經過列表生成式咱們能夠方便的生成列表。可是在有的時候,咱們須要生成的列表很是長,而咱們的計算機的內存是有限的。在操做列表的時候,咱們每每只是操做了列表的一部分區域的數據。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的迭代方式

1. next()函數

咱們能夠調用generator object的next()函數讓指針下移。例如對象

print my_generator.next() #輸出 1
print my_generator.next() #輸出 4
print my_generator.next() #輸出 9

每調用一次next(),計算出一個值,並記憶迭代到何處了。當迭代到最後一個元素後再調用next(),python則會拋出StopIteration錯誤。咱們能夠捕獲這個錯誤來處理迭代終止。
next()這種手動調用的運用較少。內存

2. 用for循環

咱們能夠利用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
相關文章
相關標籤/搜索