<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ### 導航 - [索引](../genindex.xhtml "總目錄") - [模塊](../py-modindex.xhtml "Python 模塊索引") | - [下一頁](functools.xhtml "functools --- 高階函數和可調用對象上的操作") | - [上一頁](functional.xhtml "函數式編程模塊") | - ![](https://box.kancloud.cn/a721fc7ec672275e257bbbfde49a4d4e_16x16.png) - [Python](https://www.python.org/) ? - zh\_CN 3.7.3 [文檔](../index.xhtml) ? - [Python 標準庫](index.xhtml) ? - [函數式編程模塊](functional.xhtml) ? - $('.inline-search').show(0); | # [`itertools`](#module-itertools "itertools: Functions creating iterators for efficient looping.") --- 為高效循環而創建迭代器的函數 - - - - - - 本模塊實現一系列 [iterator](../glossary.xhtml#term-iterator) ,這些迭代器受到APL,Haskell和SML的啟發。為了適用于Python,它們都被重新寫過。 本模塊標準化了一個快速、高效利用內存的核心工具集,這些工具本身或組合都很有用。它們一起形成了“迭代器代數”,這使得在純Python中有可能創建簡潔又高效的專用工具。 例如,SML有一個制表工具: `tabulate(f)`,它可產生一個序列 `f(0), f(1), ...`。在Python中可以組合 [`map()`](functions.xhtml#map "map") 和 [`count()`](#itertools.count "itertools.count") 實現: `map(f, count())`。 這些內置工具同時也能很好地與 [`operator`](operator.xhtml#module-operator "operator: Functions corresponding to the standard operators.") 模塊中的高效函數配合使用。例如,我們可以將兩個向量的點積映射到乘法運算符: `sum(map(operator.mul, vector1, vector2))` 。 **無窮迭代器:** 迭代器 實參 結果 示例 [`count()`](#itertools.count "itertools.count") start, \[step\] start, start+step, start+2\*step, ... `count(10) --> 10 11 12 13 14 ...` [`cycle()`](#itertools.cycle "itertools.cycle") p p0, p1, ... plast, p0, p1, ... `cycle('ABCD') --> A B C D A B C D ...` [`repeat()`](#itertools.repeat "itertools.repeat") elem \[,n\] elem, elem, elem, ... 重復無限次或n次 `repeat(10, 3) --> 10 10 10` **根據最短輸入序列長度停止的迭代器:** 迭代器 實參 結果 示例 [`accumulate()`](#itertools.accumulate "itertools.accumulate") p \[,func\] p0, p0+p1, p0+p1+p2, ... `accumulate([1,2,3,4,5]) --> 1 3 6 10 15` [`chain()`](#itertools.chain "itertools.chain") p, q, ... p0, p1, ... plast, q0, q1, ... `chain('ABC', 'DEF') --> A B C D E F` [`chain.from_iterable()`](#itertools.chain.from_iterable "itertools.chain.from_iterable") iterable p0, p1, ... plast, q0, q1, ... `chain.from_iterable(['ABC', 'DEF']) --> A B C D E F` [`compress()`](#itertools.compress "itertools.compress") data, selectors (d\[0\] if s\[0\]), (d\[1\] if s\[1\]), ... `compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F` [`dropwhile()`](#itertools.dropwhile "itertools.dropwhile") pred, seq seq\[n\], seq\[n+1\], ... 從pred首次真值測試失敗開始 `dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1` [`filterfalse()`](#itertools.filterfalse "itertools.filterfalse") pred, seq seq中pred(x)為假值的元素,x是seq中的元素。 `filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8` [`groupby()`](#itertools.groupby "itertools.groupby") iterable\[, key\] 根據key(v)值分組的迭代器 [`islice()`](#itertools.islice "itertools.islice") seq, \[start,\] stop \[, step\] seq\[start:stop:step\]中的元素 `islice('ABCDEFG', 2, None) --> C D E F G` [`starmap()`](#itertools.starmap "itertools.starmap") func, seq func(\*seq\[0\]), func(\*seq\[1\]), ... `starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000` [`takewhile()`](#itertools.takewhile "itertools.takewhile") pred, seq seq\[0\], seq\[1\], ..., 直到pred真值測試失敗 `takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4` [`tee()`](#itertools.tee "itertools.tee") it, n it1, it2, ... itn 將一個迭代器拆分為n個迭代器 [`zip_longest()`](#itertools.zip_longest "itertools.zip_longest") p, q, ... (p\[0\], q\[0\]), (p\[1\], q\[1\]), ... `zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-` **排列組合迭代器:** 迭代器 實參 結果 [`product()`](#itertools.product "itertools.product") p, q, ... \[repeat=1\] 笛卡爾積,相當于嵌套的for循環 [`permutations()`](#itertools.permutations "itertools.permutations") p\[, r\] 長度r元組,所有可能的排列,無重復元素 [`combinations()`](#itertools.combinations "itertools.combinations") p, r 長度r元組,有序,無重復元素 [`combinations_with_replacement()`](#itertools.combinations_with_replacement "itertools.combinations_with_replacement") p, r 長度r元組,有序,元素可重復 `product('ABCD', repeat=2)` `AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD` `permutations('ABCD', 2)` `AB AC AD BA BC BD CA CB CD DA DB DC` `combinations('ABCD', 2)` `AB AC AD BC BD CD` `combinations_with_replacement('ABCD', 2)` `AA AB AC AD BB BC BD CC CD DD` ## Itertool函數 下列模塊函數均創建并返回迭代器。有些迭代器不限制輸出流長度,所以它們只應在能截斷輸出流的函數或循環中使用。 `itertools.``accumulate`(*iterable*\[, *func*\])創建一個迭代器,返回累加和或其他二元函數的累加結果(通過可選參數 *func* 指定)。如果提供了 *func* ,它應是2個參數的函數。輸入 *iterable* 元素類型應是 *func* 能支持的任意類型。(例如,對于默認的加法操作,元素可以是任一支持加法的類型,包括 [`Decimal`](decimal.xhtml#decimal.Decimal "decimal.Decimal") 或 [`Fraction`](fractions.xhtml#fractions.Fraction "fractions.Fraction") )。如果可迭代對象的輸入為空,輸出也為空。 大致相當于: ``` def accumulate(iterable, func=operator.add): 'Return running totals' # accumulate([1,2,3,4,5]) --> 1 3 6 10 15 # accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120 it = iter(iterable) try: total = next(it) except StopIteration: return yield total for element in it: total = func(total, element) yield total ``` *func* 參數有幾種用法。它可以被設為 [`min()`](functions.xhtml#min "min") 最終得到一個最小值,或者設為 [`max()`](functions.xhtml#max "max") 最終得到一個最大值,或設為 [`operator.mul()`](operator.xhtml#operator.mul "operator.mul") 最終得到一個乘積。攤銷表可通過累加利息和支付款項得到。給iterable設置初始值并只將參數 *func* 設為累加總數可以對一階 [遞歸關系](https://en.wikipedia.org/wiki/Recurrence_relation) \[https://en.wikipedia.org/wiki/Recurrence\_relation\] 建模。 ``` >>> data = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8] >>> list(accumulate(data, operator.mul)) # running product [3, 12, 72, 144, 144, 1296, 0, 0, 0, 0] >>> list(accumulate(data, max)) # running maximum [3, 4, 6, 6, 6, 9, 9, 9, 9, 9] # Amortize a 5% loan of 1000 with 4 annual payments of 90 >>> cashflows = [1000, -90, -90, -90, -90] >>> list(accumulate(cashflows, lambda bal, pmt: bal*1.05 + pmt)) [1000, 960.0, 918.0, 873.9000000000001, 827.5950000000001] # Chaotic recurrence relation https://en.wikipedia.org/wiki/Logistic_map >>> logistic_map = lambda x, _: r * x * (1 - x) >>> r = 3.8 >>> x0 = 0.4 >>> inputs = repeat(x0, 36) # only the initial value is used >>> [format(x, '.2f') for x in accumulate(inputs, logistic_map)] ['0.40', '0.91', '0.30', '0.81', '0.60', '0.92', '0.29', '0.79', '0.63', '0.88', '0.39', '0.90', '0.33', '0.84', '0.52', '0.95', '0.18', '0.57', '0.93', '0.25', '0.71', '0.79', '0.63', '0.88', '0.39', '0.91', '0.32', '0.83', '0.54', '0.95', '0.20', '0.60', '0.91', '0.30', '0.80', '0.60'] ``` 參考一個類似函數 [`functools.reduce()`](functools.xhtml#functools.reduce "functools.reduce") ,它只返回一個最終累積值。 3\.2 新版功能. 在 3.3 版更改: 增加可選參數 *func* 。 `itertools.``chain`(*\*iterables*)創建一個迭代器,它首先返回第一個可迭代對象中所有元素,接著返回下一個可迭代對象中所有元素,直到耗盡所有可迭代對象中的元素。可將多個序列處理為單個序列。大致相當于: ``` def chain(*iterables): # chain('ABC', 'DEF') --> A B C D E F for it in iterables: for element in it: yield element ``` *classmethod* `chain.``from_iterable`(*iterable*)構建類似 [`chain()`](#itertools.chain "itertools.chain") 迭代器的另一個選擇。從一個單獨的可迭代參數中得到鏈式輸入,該參數是延遲計算的。大致相當于: ``` def from_iterable(iterables): # chain.from_iterable(['ABC', 'DEF']) --> A B C D E F for it in iterables: for element in it: yield element ``` `itertools.``combinations`(*iterable*, *r*)返回由輸入 *iterable* 中元素組成長度為 *r* 的子序列。 組合按照字典序返回。所以如果輸入 *iterable* 是有序的,生成的組合元組也是有序的。 即使元素的值相同,不同位置的元素也被認為是不同的。如果元素各自不同,那么每個組合中沒有重復元素。 大致相當于: ``` 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 = list(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) ``` [`combinations()`](#itertools.combinations "itertools.combinations") 的代碼可被改寫為 [`permutations()`](#itertools.permutations "itertools.permutations") 過濾后的子序列,(相對于元素在輸入中的位置)元素不是有序的。 ``` def combinations(iterable, r): pool = tuple(iterable) n = len(pool) for indices in permutations(range(n), r): if sorted(indices) == list(indices): yield tuple(pool[i] for i in indices) ``` 當 `0 <= r <= n` 時,返回項的個數是 `n! / r! / (n-r)!`;當 `r > n` 時,返回項個數為0。 `itertools.``combinations_with_replacement`(*iterable*, *r*)返回由輸入 *iterable* 中元素組成的長度為 *r* 的子序列,允許每個元素可重復出現。 組合按照字典序返回。所以如果輸入 *iterable* 是有序的,生成的組合元組也是有序的。 不同位置的元素是不同的,即使它們的值相同。因此如果輸入中的元素都是不同的話,返回的組合中元素也都會不同。 大致相當于: ``` def combinations_with_replacement(iterable, r): # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC pool = tuple(iterable) n = len(pool) if not n and r: return indices = [0] * r yield tuple(pool[i] for i in indices) while True: for i in reversed(range(r)): if indices[i] != n - 1: break else: return indices[i:] = [indices[i] + 1] * (r - i) yield tuple(pool[i] for i in indices) ``` [`combinations_with_replacement()`](#itertools.combinations_with_replacement "itertools.combinations_with_replacement") 的代碼可被改寫為 `production()` 過濾后的子序列,(相對于元素在輸入中的位置)元素不是有序的。 ``` def combinations_with_replacement(iterable, r): pool = tuple(iterable) n = len(pool) for indices in product(range(n), repeat=r): if sorted(indices) == list(indices): yield tuple(pool[i] for i in indices) ``` 當 `n > 0` 時,返回項個數為 `(n+r-1)! / r! / (n-1)!`. 3\.1 新版功能. `itertools.``compress`(*data*, *selectors*)創建一個迭代器,它返回 *data* 中經 *selectors* 真值測試為 `True` 的元素。迭代器在兩者較短的長度處停止。大致相當于: ``` def compress(data, selectors): # compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F return (d for d, s in zip(data, selectors) if s) ``` 3\.1 新版功能. `itertools.``count`(*start=0*, *step=1*)創建一個迭代器,它從 *start* 值開始,返回均勻間隔的值。常用于 [`map()`](functions.xhtml#map "map") 中的實參來生成連續的數據點。此外,還用于 [`zip()`](functions.xhtml#zip "zip") 來添加序列號。大致相當于: ``` def count(start=0, step=1): # count(10) --> 10 11 12 13 14 ... # count(2.5, 0.5) -> 2.5 3.0 3.5 ... n = start while True: yield n n += step ``` 當對浮點數計數時,替換為乘法代碼有時精度會更好,例如: `(start + step * i for i in count())` 。 在 3.1 版更改: 增加參數 *step* ,允許非整型。 `itertools.``cycle`(*iterable*)創建一個迭代器,返回 *iterable* 中所有元素并保存一個副本。當取完 *iterable* 中所有元素,返回副本中的所有元素。無限重復。大致相當于: ``` def cycle(iterable): # cycle('ABCD') --> A B C D A B C D A B C D ... saved = [] for element in iterable: yield element saved.append(element) while saved: for element in saved: yield element ``` 注意,該函數可能需要相當大的輔助空間(取決于 *iterable* 的長度)。 `itertools.``dropwhile`(*predicate*, *iterable*)創建一個迭代器,如果 *predicate* 為true,迭代器丟棄這些元素,然后返回其他元素。注意,迭代器在 *predicate* 首次為false之前不會產生任何輸出,所以可能需要一定長度的啟動時間。大致相當于: ``` def dropwhile(predicate, iterable): # dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1 iterable = iter(iterable) for x in iterable: if not predicate(x): yield x break for x in iterable: yield x ``` `itertools.``filterfalse`(*predicate*, *iterable*)創建一個迭代器,只返回 *iterable* 中 *predicate* 為 `False` 的元素。如果 *predicate* 是 `None`,返回真值測試為false的元素。大致相當于: ``` def filterfalse(predicate, iterable): # filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8 if predicate is None: predicate = bool for x in iterable: if not predicate(x): yield x ``` `itertools.``groupby`(*iterable*, *key=None*)創建一個迭代器,返回 *iterable* 中連續的鍵和組。*key* 是一個計算元素鍵值函數。如果未指定或為 `None`,*key* 缺省為恒等函數(identity function),返回元素不變。一般來說,*iterable* 需用同一個鍵值函數預先排序。 [`groupby()`](#itertools.groupby "itertools.groupby") 操作類似于Unix中的 `uniq`。當每次 *key* 函數產生的鍵值改變時,迭代器會分組或生成一個新組(這就是為什么通常需要使用同一個鍵值函數先對數據進行排序)。這種行為與SQL的GROUP BY操作不同,SQL的操作會忽略輸入的順序將相同鍵值的元素分在同組中。 返回的組本身也是一個迭代器,它與 [`groupby()`](#itertools.groupby "itertools.groupby") 共享底層的可迭代對象。因為源是共享的,當 [`groupby()`](#itertools.groupby "itertools.groupby") 對象向后迭代時,前一個組將消失。因此如果稍后還需要返回結果,可保存為列表: ``` groups = [] uniquekeys = [] data = sorted(data, key=keyfunc) for k, g in groupby(data, keyfunc): groups.append(list(g)) # Store group iterator as a list uniquekeys.append(k) ``` [`groupby()`](#itertools.groupby "itertools.groupby") 大致相當于: ``` class groupby: # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D def __init__(self, iterable, key=None): if key is None: key = lambda x: x self.keyfunc = key self.it = iter(iterable) self.tgtkey = self.currkey = self.currvalue = object() def __iter__(self): return self def __next__(self): self.id = object() while self.currkey == self.tgtkey: self.currvalue = next(self.it) # Exit on StopIteration self.currkey = self.keyfunc(self.currvalue) self.tgtkey = self.currkey return (self.currkey, self._grouper(self.tgtkey, self.id)) def _grouper(self, tgtkey, id): while self.id is id and self.currkey == tgtkey: yield self.currvalue try: self.currvalue = next(self.it) except StopIteration: return self.currkey = self.keyfunc(self.currvalue) ``` `itertools.``islice`(*iterable*, *stop*)`itertools.``islice`(*iterable*, *start*, *stop*\[, *step*\])創建一個迭代器,返回從 *iterable* 里選中的元素。如果 *start* 不是0,跳過 *iterable* 中的元素,直到到達 *start* 這個位置。之后迭代器連續返回元素,除非 *step* 設置的值很高導致被跳過。如果 *stop* 為 `None`,迭代器耗光為止;否則,在指定的位置停止。與普通的切片不同,[`islice()`](#itertools.islice "itertools.islice") 不支持將 *start* , *stop* ,或 *step* 設為負值。可用來從內部數據結構被壓平的數據中提取相關字段(例如一個多行報告,它的名稱字段出現在每三行上)。大致相當于: ``` def islice(iterable, *args): # islice('ABCDEFG', 2) --> A B # islice('ABCDEFG', 2, 4) --> C D # islice('ABCDEFG', 2, None) --> C D E F G # islice('ABCDEFG', 0, None, 2) --> A C E G s = slice(*args) start, stop, step = s.start or 0, s.stop or sys.maxsize, s.step or 1 it = iter(range(start, stop, step)) try: nexti = next(it) except StopIteration: # Consume *iterable* up to the *start* position. for i, element in zip(range(start), iterable): pass return try: for i, element in enumerate(iterable): if i == nexti: yield element nexti = next(it) except StopIteration: # Consume to *stop*. for i, element in zip(range(i + 1, stop), iterable): pass ``` 如果 *start* 為 `None`,迭代從0開始。如果 *step* 為 `None` ,步長缺省為1。 `itertools.``permutations`(*iterable*, *r=None*)連續返回由 *iterable* 元素生成長度為 *r* 的排列。 如果 *r* 未指定或為 `None` ,*r* 默認設置為 *iterable* 的長度,這種情況下,生成所有全長排列。 排列依字典序發出。因此,如果 *iterable* 是已排序的,排列元組將有序地產出。 即使元素的值相同,不同位置的元素也被認為是不同的。如果元素值都不同,每個排列中的元素值不會重復。 大致相當于: ``` def permutations(iterable, r=None): # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC # permutations(range(3)) --> 012 021 102 120 201 210 pool = tuple(iterable) n = len(pool) r = n if r is None else r if r > n: return indices = list(range(n)) cycles = list(range(n, n-r, -1)) yield tuple(pool[i] for i in indices[:r]) while n: for i in reversed(range(r)): cycles[i] -= 1 if cycles[i] == 0: indices[i:] = indices[i+1:] + indices[i:i+1] cycles[i] = n - i else: j = cycles[i] indices[i], indices[-j] = indices[-j], indices[i] yield tuple(pool[i] for i in indices[:r]) break else: return ``` [`permutations()`](#itertools.permutations "itertools.permutations") 的代碼也可被改寫為 [`product()`](#itertools.product "itertools.product") 的子序列,只要將含有重復元素(來自輸入中同一位置的)的項排除。 ``` def permutations(iterable, r=None): pool = tuple(iterable) n = len(pool) r = n if r is None else r for indices in product(range(n), repeat=r): if len(set(indices)) == r: yield tuple(pool[i] for i in indices) ``` 當 `0 <= r <= n` ,返回項個數為 `n! / (n-r)!` ;當 `r > n` ,返回項個數為0。 `itertools.``product`(*\*iterables*, *repeat=1*)可迭代對象輸入的笛卡兒積。 大致相當于生成器表達式中的嵌套循環。例如, `product(A, B)` 和 `((x,y) for x in A for y in B)` 返回結果一樣。 嵌套循環像里程表那樣循環變動,每次迭代時將最右側的元素向后迭代。這種模式形成了一種字典序,因此如果輸入的可迭代對象是已排序的,笛卡爾積元組依次序發出。 要計算可迭代對象自身的笛卡爾積,將可選參數 *repeat* 設定為要重復的次數。例如,`product(A, repeat=4)` 和 `product(A, A, A, A)` 是一樣的。 該函數大致相當于下面的代碼,只不過實際實現方案不會在內存中創建中間結果。 ``` def product(*args, repeat=1): # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 pools = [tuple(pool) for pool in args] * repeat result = [[]] for pool in pools: result = [x+[y] for x in result for y in pool] for prod in result: yield tuple(prod) ``` `itertools.``repeat`(*object*\[, *times*\])創建一個迭代器,不斷重復 *object* 。除非設定參數 *times* ,否則將無限重復。可用于 [`map()`](functions.xhtml#map "map") 函數中的參數,被調用函數可得到一個不變參數。也可用于 [`zip()`](functions.xhtml#zip "zip") 的參數以在元組記錄中創建一個不變的部分。 大致相當于: ``` def repeat(object, times=None): # repeat(10, 3) --> 10 10 10 if times is None: while True: yield object else: for i in range(times): yield object ``` *repeat* 最常見的用途就是在 *map* 或 *zip* 提供一個常量流: ``` >>> list(map(pow, range(10), repeat(2))) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] ``` `itertools.``starmap`(*function*, *iterable*)創建一個迭代器,使用從可迭代對象中獲取的參數來計算該函數。當參數對應的形參已從一個單獨可迭代對象組合為元組時(數據已被“預組對”)可用此函數代替 [`map()`](functions.xhtml#map "map")。[`map()`](functions.xhtml#map "map") 與 [`starmap()`](#itertools.starmap "itertools.starmap") 之間的區別可以類比 `function(a,b)` 與 `function(*c)` 的區別。大致相當于: ``` def starmap(function, iterable): # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000 for args in iterable: yield function(*args) ``` `itertools.``takewhile`(*predicate*, *iterable*)創建一個迭代器,只要 predicate 為真就從可迭代對象中返回元素。大致相當于: ``` def takewhile(predicate, iterable): # takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4 for x in iterable: if predicate(x): yield x else: break ``` `itertools.``tee`(*iterable*, *n=2*)從一個可迭代對象中返回 *n* 個獨立的迭代器。 下面的Python代碼能幫助解釋 *tee* 做了什么(盡管實際的實現更復雜,而且僅使用了一個底層的 FIFO 隊列)。 大致相當于: ``` def tee(iterable, n=2): it = iter(iterable) deques = [collections.deque() for i in range(n)] def gen(mydeque): while True: if not mydeque: # when the local deque is empty try: newval = next(it) # fetch a new value and except StopIteration: return for d in deques: # load it to all the deques d.append(newval) yield mydeque.popleft() return tuple(gen(d) for d in deques) ``` 一旦 [`tee()`](#itertools.tee "itertools.tee") 實施了一次分裂,原有的 *iterable* 不應再被使用;否則tee對象無法得知 *iterable* 可能已向后迭代。 該迭代工具可能需要相當大的輔助存儲空間(這取決于要保存多少臨時數據)。通常,如果一個迭代器在另一個迭代器開始之前就要使用大部份或全部數據,使用 [`list()`](stdtypes.xhtml#list "list") 會比 [`tee()`](#itertools.tee "itertools.tee") 更快。 `itertools.``zip_longest`(*\*iterables*, *fillvalue=None*)創建一個迭代器,從每個可迭代對象中收集元素。如果可迭代對象的長度未對齊,將根據 *fillvalue* 填充缺失值。迭代持續到耗光最長的可迭代對象。大致相當于: ``` def zip_longest(*args, fillvalue=None): # zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D- iterators = [iter(it) for it in args] num_active = len(iterators) if not num_active: return while True: values = [] for i, it in enumerate(iterators): try: value = next(it) except StopIteration: num_active -= 1 if not num_active: return iterators[i] = repeat(fillvalue) value = fillvalue values.append(value) yield tuple(values) ``` 如果其中一個可迭代對象有無限長度,[`zip_longest()`](#itertools.zip_longest "itertools.zip_longest") 函數應封裝在限制調用次數的場景中(例如 [`islice()`](#itertools.islice "itertools.islice") 或 [`takewhile()`](#itertools.takewhile "itertools.takewhile"))。除非指定, *fillvalue* 默認為 `None` 。 ## Itertools食譜 本節將展示如何使用現有的itertools作為基礎構件來創建擴展的工具集。 擴展的工具提供了與底層工具集相同的高性能。保持了超棒的內存利用率,因為一次只處理一個元素,而不是將整個可迭代對象加載到內存。代碼量保持得很小,以函數式風格將這些工具連接在一起,有助于消除臨時變量。速度依然很快,因為傾向于使用“矢量化”構件來取代解釋器開銷大的 for 循環和 [generator](../glossary.xhtml#term-generator) 。 ``` def take(n, iterable): "Return first n items of the iterable as a list" return list(islice(iterable, n)) def prepend(value, iterator): "Prepend a single value in front of an iterator" # prepend(1, [2, 3, 4]) -> 1 2 3 4 return chain([value], iterator) def tabulate(function, start=0): "Return function(0), function(1), ..." return map(function, count(start)) def tail(n, iterable): "Return an iterator over the last n items" # tail(3, 'ABCDEFG') --> E F G return iter(collections.deque(iterable, maxlen=n)) def consume(iterator, n=None): "Advance the iterator n-steps ahead. If n is None, consume entirely." # Use functions that consume iterators at C speed. if n is None: # feed the entire iterator into a zero-length deque collections.deque(iterator, maxlen=0) else: # advance to the empty slice starting at position n next(islice(iterator, n, n), None) def nth(iterable, n, default=None): "Returns the nth item or a default value" return next(islice(iterable, n, None), default) def all_equal(iterable): "Returns True if all the elements are equal to each other" g = groupby(iterable) return next(g, True) and not next(g, False) def quantify(iterable, pred=bool): "Count how many times the predicate is true" return sum(map(pred, iterable)) def padnone(iterable): """Returns the sequence elements and then returns None indefinitely. Useful for emulating the behavior of the built-in map() function. """ return chain(iterable, repeat(None)) def ncycles(iterable, n): "Returns the sequence elements n times" return chain.from_iterable(repeat(tuple(iterable), n)) def dotproduct(vec1, vec2): return sum(map(operator.mul, vec1, vec2)) def flatten(listOfLists): "Flatten one level of nesting" return chain.from_iterable(listOfLists) def repeatfunc(func, times=None, *args): """Repeat calls to func with specified arguments. Example: repeatfunc(random.random) """ if times is None: return starmap(func, repeat(args)) return starmap(func, repeat(args, times)) def pairwise(iterable): "s -> (s0,s1), (s1,s2), (s2, s3), ..." a, b = tee(iterable) next(b, None) return zip(a, b) def grouper(iterable, n, fillvalue=None): "Collect data into fixed-length chunks or blocks" # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx" args = [iter(iterable)] * n return zip_longest(*args, fillvalue=fillvalue) def roundrobin(*iterables): "roundrobin('ABC', 'D', 'EF') --> A D E B F C" # Recipe credited to George Sakkis num_active = len(iterables) nexts = cycle(iter(it).__next__ for it in iterables) while num_active: try: for next in nexts: yield next() except StopIteration: # Remove the iterator we just exhausted from the cycle. num_active -= 1 nexts = cycle(islice(nexts, num_active)) def partition(pred, iterable): 'Use a predicate to partition entries into false entries and true entries' # partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 t1, t2 = tee(iterable) return filterfalse(pred, t1), filter(pred, t2) def powerset(iterable): "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" s = list(iterable) return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) def unique_everseen(iterable, key=None): "List unique elements, preserving order. Remember all elements ever seen." # unique_everseen('AAAABBBCCDAABBB') --> A B C D # unique_everseen('ABBCcAD', str.lower) --> A B C D seen = set() seen_add = seen.add if key is None: for element in filterfalse(seen.__contains__, iterable): seen_add(element) yield element else: for element in iterable: k = key(element) if k not in seen: seen_add(k) yield element def unique_justseen(iterable, key=None): "List unique elements, preserving order. Remember only the element just seen." # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B # unique_justseen('ABBCcAD', str.lower) --> A B C A D return map(next, map(itemgetter(1), groupby(iterable, key))) def iter_except(func, exception, first=None): """ Call a function repeatedly until an exception is raised. Converts a call-until-exception interface to an iterator interface. Like builtins.iter(func, sentinel) but uses an exception instead of a sentinel to end the loop. Examples: iter_except(functools.partial(heappop, h), IndexError) # priority queue iterator iter_except(d.popitem, KeyError) # non-blocking dict iterator iter_except(d.popleft, IndexError) # non-blocking deque iterator iter_except(q.get_nowait, Queue.Empty) # loop over a producer Queue iter_except(s.pop, KeyError) # non-blocking set iterator """ try: if first is not None: yield first() # For database APIs needing an initial cast to db.first() while True: yield func() except exception: pass def first_true(iterable, default=False, pred=None): """Returns the first true value in the iterable. If no true value is found, returns *default* If *pred* is not None, returns the first item for which pred(item) is true. """ # first_true([a,b,c], x) --> a or b or c or x # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x return next(filter(pred, iterable), default) def random_product(*args, repeat=1): "Random selection from itertools.product(*args, **kwds)" pools = [tuple(pool) for pool in args] * repeat return tuple(random.choice(pool) for pool in pools) def random_permutation(iterable, r=None): "Random selection from itertools.permutations(iterable, r)" pool = tuple(iterable) r = len(pool) if r is None else r return tuple(random.sample(pool, r)) def random_combination(iterable, r): "Random selection from itertools.combinations(iterable, r)" pool = tuple(iterable) n = len(pool) indices = sorted(random.sample(range(n), r)) return tuple(pool[i] for i in indices) def random_combination_with_replacement(iterable, r): "Random selection from itertools.combinations_with_replacement(iterable, r)" pool = tuple(iterable) n = len(pool) indices = sorted(random.randrange(n) for i in range(r)) return tuple(pool[i] for i in indices) def nth_combination(iterable, r, index): 'Equivalent to list(combinations(iterable, r))[index]' pool = tuple(iterable) n = len(pool) if r < 0 or r > n: raise ValueError c = 1 k = min(r, n-r) for i in range(1, k+1): c = c * (n - k + i) // i if index < 0: index += c if index < 0 or index >= c: raise IndexError result = [] while r: c, n, r = c*r//n, n-1, r-1 while index >= c: index -= c c, n = c*(n-r)//n, n-1 result.append(pool[-1-n]) return tuple(result) ``` 注意,通過將全局查找替換為局部變量的缺省值,上述配方中有很多可以這樣優化。例如, *dotproduct* 配方可以這樣寫: ``` def dotproduct(vec1, vec2, sum=sum, map=map, mul=operator.mul): return sum(map(mul, vec1, vec2)) ``` ### 導航 - [索引](../genindex.xhtml "總目錄") - [模塊](../py-modindex.xhtml "Python 模塊索引") | - [下一頁](functools.xhtml "functools --- 高階函數和可調用對象上的操作") | - [上一頁](functional.xhtml "函數式編程模塊") | - ![](https://box.kancloud.cn/a721fc7ec672275e257bbbfde49a4d4e_16x16.png) - [Python](https://www.python.org/) ? - zh\_CN 3.7.3 [文檔](../index.xhtml) ? - [Python 標準庫](index.xhtml) ? - [函數式編程模塊](functional.xhtml) ? - $('.inline-search').show(0); | ? [版權所有](../copyright.xhtml) 2001-2019, Python Software Foundation. Python 軟件基金會是一個非盈利組織。 [請捐助。](https://www.python.org/psf/donations/) 最后更新于 5月 21, 2019. [發現了問題](../bugs.xhtml)? 使用[Sphinx](http://sphinx.pocoo.org/)1.8.4 創建。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看