官方對itertools的定義是Functions creating iterators for efficient looping
,定義了一系列的方法,能幫助我們建立能夠進行高效遍歷迭代的迭代器,裡面包含不少有意思並且有用的方法,比如像chain
, izip/izip_longest
, combinations
, ifilter
等等。
在這裡簡單拿幾個方法為例,簡單分析一下文件裡面給出的等效的實現的方式還有平時我們能夠使用的場景。
chain
如同chain
的名稱還有簽名itertools.chain(*iterables)
所示,我們能用它將一系列的可迭代物件串聯起來,這樣就能連續的對多個迭代物件的內容進行迭代:
1 2 3 4 5 6 |
>>> itertools.chain('ABC', 'DEF') <itertools.chain object at 0x718910> >>> for item in itertools.chain('ABC', 'DEF'): ... print item, ... A B C D E F |
從上面的列印日誌裡面能夠看到,呼叫itertools.chain
生成了一個迭代器物件,在python的itertools
內建庫裡面,chain
被實現成一個繼承自object
的一個物件,實現了next, __iter__
方法(將自己實現成一個可迭代物件,迭代器),呼叫時其實是呼叫它的__init__(self, *iterables)
方法初始化了一個物件,然後接下來進行迭代。簡化的等效的實現方式類似:
1 2 3 4 |
def chain(*iterables): for it in iterables: for element in it: yield element |
傳遞給chain
的多個可迭代物件唄儲存在元組型別的變數iterables
裡面,遍歷每一個可迭代物件裡面的每一個物件,上面等效實現的方式裡面是用yield
的實現的,當對串聯的結果比如說用for
進行遍歷的時候,yield
能夠每次返回一條資料,中斷,外面我們自己的程式碼執行(或輸出或其它的操作)如此迴圈反覆知道遍歷結束(StopIteration error throwed)。
combinations
這個方法能夠幫助我們生成一個列表中,按照順序能夠有的所有組合,當然生成依然是迭代器物件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
>>> itertools.combinations('ABCDA', 2) <itertools.combinations object at 0x714720> >>> for item in itertools.combinations('ABCDA', 2): ... print item ... ('A', 'B') ('A', 'C') ('A', 'D') ('A', 'A') ('B', 'C') ('B', 'D') ('B', 'A') ('C', 'D') ('C', 'A') ('D', 'A') |
和chain
的實現方式差不多是一樣的,實現了next, __iter__
方法(將自己實現成一個可迭代物件,迭代器),呼叫時其實是呼叫它的__init__(self, iterable, r)
方法初始化了一個combinations
物件,然後能夠對它進行迭代。等效的實現方式差不多像這樣:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
def combinations(iterable, r): # combinations('ABCD', 2) --> AB AC AD BC BD CD # combinations(range(4), 3) --> 012 013 023 123 pool = tuple(iterable) n = len(pool) if r > n: return indices = range(r) yield tuple(pool[i] for i in indices) while True: for i in reversed(range(r)): if indices[i] != i + n - r: break else: return indices[i] += 1 for j in range(i+1, r): indices[j] = indices[j-1] + 1 yield tuple(pool[i] for i in indices) |
其實這個等效的實現的方式也很有意思,裡面充分你的利用了yield
的特性,中斷返回值後能夠將現場的環境保持下來,比如例子中,變數indices
的值在每次返回值之後都能繼續儲存,這樣裡面記錄的索引值才能正確遞進,直到迭代結束。
itertools
這個內建庫裡面的提供的一些服用方法能夠很大簡化平時需要做的一些工作,而且高效。也能方便結合operator
裡面的一些計算的方法一起使用,程式碼能精簡很多。官方的文件裡面詳細的介紹了各個方法的實現和使用,希望這篇流水賬能夠起個引言的作用。
參考資料:itertools — Functions creating iterators for efficient looping