理解新概念
Python V2.2 中引入了迭代器的思想。唔,這并不十分正確;這種思想的“苗頭”早已出現在較老的函數 xrange() 以及文件方法 .xreadlines() 中了。通過引入 yield 關鍵字,Python 2.2 在內部實現的許多方面推廣了這一概念,并使編程定制迭代器變得更為簡單( yield 的出現使函數轉換成生成器,而生成器反過來又返回迭代器)。
迭代器背后的動機有兩方面。將數據作為序列處理通常是最簡單的方法,而以線性順序處理的序列通常并不需要都同時實際 存在。
x*() 前兆提供了這些原理的清晰示例。如果您想對某操作執行成千上萬次,那么執行您的程序可能要花些時間,但該程序一般不需要占用大量內存。同樣,對于許多類型的文件,可以一行一行地處理,且不需要將整個文件存儲在內存中。最好對其它所有種類的序列也進行惰性處理;它們可能依賴于通過通道逐步到達的數據,或者依賴于一步一步執行的計算。
大多數時候,迭代器用在 for 循環內,就象真正的序列那樣。迭代器提供了 .next() 方法,它可以被顯式調用,但有百分之九十九的可能,您所看到的是以下行:
for x in iterator: do_something_with(x)
在對 iterator.next() 進行幕后調用而產生 StopIteration 異常時,該循環就被終止。順便說一下,通過調用 iter(seq) ,實際序列可以被轉換成迭代器 - 這不會節省任何內存,但是在下面討論的函數中它會很有用。
Python 不斷發展的分裂性格
Python 對函數編程(FP)的觀點有點相互矛盾。一方面,許多 Python 開發人員輕視傳統的 FP 函數 map() 、 filter() 和 reduce() ,常常建議使用“列表理解”來代替它們。但完整的 itertools 模塊恰恰是由與這些函數類型完全相同的函數組成的,只不過這些函數對“惰性序列”(迭代器)操作,而不是對完整的序列(列表,元組)操作。而且,Python 2.3 中沒有任何“迭代器理解”的語法,這似乎與列表理解擁有一樣的動機。
我猜想 Python 最終會產生某種形式的迭代器理解,但這取決于找到合適于它們的自然語法。同時,在 itertools 模塊中,我們擁有大量有用的組合函數。大致地,這些函數中的每一個都接受一些參數(通常包含一些基礎迭代器)并返回一個新迭代器。例如,函數 ifilter() 、 imap() 和 izip() 都分別直接等同于缺少詞首 i 的內置函數。
缺少的等價函數
itertools 中沒有 ireduce() ,盡管按道理很自然地應該有這個函數;可能的 Python 實現是:
清單 1. ireduce() 的樣本實現
def ireduce(func, iterable, init=None): if init is None: iterable = iter(iterable) curr = iterable.next() else: curr = init for x in iterable: curr = func(curr, x) yield curr
新聞熱點
疑難解答