粗談Python內建庫itertools

發表於2016-01-22

官方對itertools的定義是Functions creating iterators for efficient looping,定義了一系列的方法,能幫助我們建立能夠進行高效遍歷迭代的迭代器,裡面包含不少有意思並且有用的方法,比如像chain, izip/izip_longest, combinations, ifilter等等。

在這裡簡單拿幾個方法為例,簡單分析一下文件裡面給出的等效的實現的方式還有平時我們能夠使用的場景。

chain

如同chain的名稱還有簽名itertools.chain(*iterables)所示,我們能用它將一系列的可迭代物件串聯起來,這樣就能連續的對多個迭代物件的內容進行迭代:

從上面的列印日誌裡面能夠看到,呼叫itertools.chain生成了一個迭代器物件,在python的itertools內建庫裡面,chain被實現成一個繼承自object的一個物件,實現了next, __iter__方法(將自己實現成一個可迭代物件,迭代器),呼叫時其實是呼叫它的__init__(self, *iterables)方法初始化了一個物件,然後接下來進行迭代。簡化的等效的實現方式類似:

傳遞給chain的多個可迭代物件唄儲存在元組型別的變數iterables裡面,遍歷每一個可迭代物件裡面的每一個物件,上面等效實現的方式裡面是用yield的實現的,當對串聯的結果比如說用for進行遍歷的時候,yield能夠每次返回一條資料,中斷,外面我們自己的程式碼執行(或輸出或其它的操作)如此迴圈反覆知道遍歷結束(StopIteration error throwed)。

combinations

這個方法能夠幫助我們生成一個列表中,按照順序能夠有的所有組合,當然生成依然是迭代器物件。

chain的實現方式差不多是一樣的,實現了next, __iter__方法(將自己實現成一個可迭代物件,迭代器),呼叫時其實是呼叫它的__init__(self, iterable, r)方法初始化了一個combinations物件,然後能夠對它進行迭代。等效的實現方式差不多像這樣:

其實這個等效的實現的方式也很有意思,裡面充分你的利用了yield的特性,中斷返回值後能夠將現場的環境保持下來,比如例子中,變數indices的值在每次返回值之後都能繼續儲存,這樣裡面記錄的索引值才能正確遞進,直到迭代結束。

itertools這個內建庫裡面的提供的一些服用方法能夠很大簡化平時需要做的一些工作,而且高效。也能方便結合operator裡面的一些計算的方法一起使用,程式碼能精簡很多。官方的文件裡面詳細的介紹了各個方法的實現和使用,希望這篇流水賬能夠起個引言的作用。

參考資料:itertools — Functions creating iterators for efficient looping

相關文章