itertools --- 建立產生高效率迴圈之疊代器的函式¶
這個模組實作了許多 疊代器 (iterator) 構建塊 (building block),其靈感來自 APL、Haskell 和 SML 的結構。每個構建塊都以適合 Python 的形式來重新設計。
這個模組標準化了快速且高效率利用記憶體的核心工具集,這些工具本身或組合使用都很有用。它們共同構成了一個「疊代器代數 (iterator algebra)」,使得在純 Python 中簡潔且高效地建構專用工具成為可能。
例如,SML 提供了一個造表工具:tabulate(f),它產生一個序列 f(0), f(1), ...。在 Python 中,可以透過結合 map() 和 count() 組成 map(f, count()) 以達到同樣的效果。
一般疊代器:
疊代器 |
引數 |
結果 |
範例 |
|---|---|---|---|
p [,func] |
p0, p0+p1, p0+p1+p2, ... |
|
|
p, n |
(p0, p1, ..., p_n-1), ... |
|
|
p, q, ... |
p0, p1, ... plast, q0, q1, ... |
|
|
可疊代物件 |
p0, p1, ... plast, q0, q1, ... |
|
|
data, selectors |
(d[0] if s[0]), (d[1] if s[1]), ... |
|
|
[start[, step]] |
start, start+step, start+2*step, ... |
|
|
p |
p0, p1, ... plast, p0, p1, ... |
|
|
predicate, seq |
seq[n], seq[n+1],當 predicate 失敗時開始 |
|
|
predicate, seq |
當 predicate(elem) 失敗時 seq 的元素 |
|
|
iterable[, key] |
根據 key(v) 的值分組的子疊代器 |
|
|
seq, [start,] stop [, step] |
seq[start:stop:step] 的元素 |
|
|
可疊代物件 |
(p[0], p[1]), (p[1], p[2]) |
|
|
elem [,n] |
elem, elem, elem,... 重複無限次或 n 次 |
|
|
func, seq |
func(*seq[0]), func(*seq[1]), ... |
|
|
predicate, seq |
seq[0], seq[1],直到 predicate 失敗 |
|
|
it, n |
it1, it2, ... itn,將一個疊代器分成 n 個 |
|
|
p, q, ... |
(p[0], q[0]), (p[1], q[1]), ... |
|
組合疊代器:
疊代器 |
引數 |
結果 |
|---|---|---|
p, q, ... [repeat=1] |
笛卡爾乘積 (cartesian product),相當於巢狀的 for 迴圈 |
|
p[, r] |
長度為 r 的元組,所有可能的定序,無重複元素 |
|
p, r |
長度為 r 的元組,按照排序過後的定序,無重複元素 |
|
p, r |
長度為 r 的元組,按照排序過後的定序,有重複元素 |
範例 |
結果 |
|---|---|
|
|
|
|
|
|
|
|
Itertool 函式¶
以下的函式都會建構並回傳疊代器。一些函式提供無限長度的串流 (stream),因此應僅由截斷串流的函式或迴圈來存取它們。
- itertools.accumulate(iterable[, function, *, initial=None])¶
建立一個回傳累積和的疊代器,或其他二進位函式的累積結果。
function 預設為加法。function 應接受兩個引數,即累積總和和來自 iterable 的值。
如果提供了 initial 值,則累積將從該值開始,並且輸出的元素數將比輸入的可疊代物件多一個。
大致等價於:
def accumulate(iterable, function=operator.add, *, initial=None): 'Return running totals' # accumulate([1,2,3,4,5]) → 1 3 6 10 15 # accumulate([1,2,3,4,5], initial=100) → 100 101 103 106 110 115 # accumulate([1,2,3,4,5], operator.mul) → 1 2 6 24 120 iterator = iter(iterable) total = initial if initial is None: try: total = next(iterator) except StopIteration: return yield total for element in iterator: total = function(total, element) yield total
function 引數可以被設定為
min()以得到連續的最小值,設定為max()以得到連續的最大值,或者設定為operator.mul()以得到連續的乘積。也可以透過累積利息和付款來建立攤銷表 (Amortization tables) :>>> data = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8] >>> list(accumulate(data, max)) # 運行最大值 [3, 4, 6, 6, 6, 9, 9, 9, 9, 9] >>> list(accumulate(data, operator.mul)) # 運行乘積 [3, 12, 72, 144, 144, 1296, 0, 0, 0, 0] # 攤銷一筆 1000 的 5% 貸款,分 10 年、每年支付 90 >>> update = lambda balance, payment: round(balance * 1.05) - payment >>> list(accumulate(repeat(90, 10), update, initial=1_000)) [1000, 960, 918, 874, 828, 779, 728, 674, 618, 559, 497]
可參見
functools.reduce(),其是個類似的函式,但僅回傳最終的累積值。在 3.2 版被加入.
在 3.3 版的變更: 新增可選的 function 參數。
在 3.8 版的變更: 新增可選的 initial 參數。
- itertools.batched(iterable, n, *,