一、迭代器(iterator)
在python中,for迴圈可以用於python中的任何型別,包括列表、元祖等等,實際上,for迴圈可用於任何「可迭代物件」,這其實就是迭代器
迭代器是乙個實現了迭代器協議的物件,python中的迭代器協議就是有next方法的物件會前進到下一結果,而在一系列結果的末尾是,則會引發stopiteration。任何這類的物件在python中都可以用for迴圈或其他遍歷工具迭代,迭代工具內部會在每次迭代時呼叫next方法,並且捕捉stopiteration異常來確定何時離開。
使用迭代器乙個顯而易見的好處就是:每次只從物件中讀取一條資料,不會造成記憶體的過大開銷。
比如要逐行讀取乙個檔案的內容,利用readlines()方法,我們可以這麼寫:
12
for line in open("test.txt").readlines():這樣雖然可以工作,但不是最好的方法。因為他實際上是把檔案一次載入到記憶體中,然後逐行列印。當檔案很大時,這個方法的記憶體開銷就很大了。print line
利用file的迭代器,我們可以這樣寫:
12
for line in open("test.txt"): #use file iterators這是最簡單也是執行速度最快的寫法,他並沒顯式的讀取檔案,而是利用迭代器每次讀取下一行。print line
二、生成器(constructor)
生成器函式在python中與迭代器協議的概念聯絡在一起。簡而言之,包含yield語句的函式會被特地編譯成生成器。當函式被呼叫時,他們返回乙個生成器物件,這個物件支援迭代器介面。函式也許會有個return語句,但它的作用是用來yield產生值的。
不像一般的函式會生成值後退出,生成器函式在生成值後會自動掛起並暫停他們的執行和狀態,他的本地變數將儲存狀態資訊,這些資訊在函式恢復時將再度有效
1234567
8
>>> def g(n):要了解他的執行原理,我們來用next方法看看:... for i in range(n):
... yield i **2
...>>> for i in g(5):
... print i,":",
...0 : 1 : 4 : 9 : 16 :
1234567
891011
1213
1415
>>> t = g(5)在執行完5次next之後,生成器丟擲了乙個stopiteration異常,迭代終止。>>> t.next()
0>>> t.next()
1>>> t.next()
4>>> t.next()
9>>> t.next()
16>>> t.next()
traceback (most recent call last):
file "", line 1, in
stopiteration
再來看乙個yield的例子,用生成器生成乙個fibonacci數列:
1234567
8910
def fab(max):看到這裡應該就能理解生成器那個很抽象的概念了吧~~a,b = 0,1
while a < max:
yield a
a, b = b, a+b
>>> for i in fab(20):
... print i,",",
...0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 ,
def read_file(fpath):如果直接對檔案物件呼叫 read() 方法,會導致不可**的記憶體占用。好的方法是利用固定長度的緩衝區來不斷讀取檔案內容。通過 yield,我們不再需要編寫讀檔案的迭代類,就可以輕鬆實現檔案讀取。block_size = 1024
with open(fpath, 'rb') as f:
while true:
block = f.read(block_size)
if block:
yield block
else:
return
python之生成器和迭代器
迭代 遍歷挨個取元素 a 1,2,3,4,5,6 for i in a print i 1,2,3,4,5,6 可迭代物件 實現了迭代器的物件 在產生這個物件的類中定義了 iter 方法 迭代器 迭代器在類中實現了兩個物件 iter 方法 返回迭代器物件本身 next 方法 返回下乙個元素 這裡需要...
python之迭代器和生成器
要將生成器,先講一下列表生成式。列表生成式 如果我們要建立乙個有規律的列表,比如說1 10 list1 1,2,3,4,5,6,7,8,9,10 list1 i for i in range 1,11 列表生成式 print list1 print list1 2 1,2,3,4,5,6,7,8,9...
python之生成器和迭代器
生成器表示式 返回乙個物件,這個物件只有在需要的時候才產生結果 生成器函式 為什麼叫生成器函式?因為它隨著時間的推移生成了乙個數值佇列。一般的函式在執行完畢之後會返回乙個值然後退出,但是生成器函式會自動掛起,然後重新拾起急需執行,他會利用yield關鍵字關起函式,給呼叫者返回乙個值,同時保留了當前的...