Python 函式建立迭代器以實現高效迴圈


與大多數程式語言一樣,Python 提供 while 和 for 語句來構成迴圈結構。for 語句特別適用於遍歷可迭代物件,例如列表、元組或字串。Python 標準庫中的 itertools 模組定義了更有效和快速的迭代工具。這些迭代器構建塊是類似 Haskell 和 SML 等函數語言程式設計語言中類似工具的 Python 風格實現。

itertools 模組中的函式分為三種類型。

  • 無限迭代器
  • 有限迭代器
  • 組合迭代器

以下函式生成無限序列。

count() − 此函式返回從起始值開始的等間距值的迭代器。該函式可以具有可選的步長值,以該間隔遞增後續值。

>>> from itertools import count
>>> for x in count(20):
print (x)
>>> for x in count(100,10):
print (x)

第一個語句將生成從 20 開始的無限序列,第二個語句將生成從 100 開始,步長為 10 的數字。請注意,這些迴圈是無限的,不會自行終止。它們將在按下 Ctrl-C 時終止。

cycle() − 此函式開始返回給定可迭代物件中的每個元素並儲存其副本。一旦元素耗盡,就會返回儲存的副本中的元素,從而形成無限迴圈。

>>> from itertools import cycle
>>> for x in cycle("hello"):
print (x)

字串中的字元將重複列印,直到發出鍵盤中斷 Ctrl-C。

repeat() − 此函式重複返回物件引數。如果提供了第二個引數“times”,則重複該次數。

>>> from itertools import repeat
>>> for x in repeat(1):
print (x)
>>> for x in repeat('hello', 10):
print (x)

第一個迴圈將無限列印 1。第二個迴圈列印“hello”10 次。

以下類別中的函式返回在最短輸入序列上終止的有限迭代器。

accumulate() − 此函式有兩個引數。第一個是可迭代物件(列表、元組或字串)。第二個引數預設為 operator.add()(operator 模組中實現標準加法運算子的函式),但可以是任何其他接收兩個數字引數的函式。

accumulate(sequence, func)

輸入序列的前兩個元素由 func 處理。處理結果是下一次迭代的第一個引數,而 func 的第二個引數是輸入序列中的第三個元素。此過程重複,直到序列耗盡。accumulate 函式返回一個迭代器,其中每個元素都是處理連續元素的累積結果。

在以下示例中,列表中的數字被累加。請注意,預設函式引數是加法運算。

>>> from itertools import accumulate
>>> list(accumulate([1,2,3,4,5]))
[1, 3, 6, 10, 15]

我們可以將使用者定義的函式作為 accumulate() 函式的第二個引數。

>>> def multiply(x,y):
return x*y
>>> list(accumulate([1,2,3,4,5], multiply))
[1, 2, 6, 24, 120]

此行為有點類似於內建的 reduce() 函式。reduce() 函式僅返回累積的最終結果,而 accumulate() 構建所有中間結果的迭代器。

chain() − 此函式可以有多個可迭代物件作為引數。它將第一個可迭代物件的每個元素生成到結果迭代器中,並繼續進行下一個,直到可迭代物件引數耗盡。

>>> from itertools import chain
>>> list(chain([10,20],'hello',range(4)))
[10, 20, 'h', 'e', 'l', 'l', 'o', 0, 1, 2, 3]

dropwhile() − 此函式透過丟棄可迭代物件的元素返回一個迭代器,只要謂詞函式引數返回 true。一旦函式返回 false,所有剩餘的元素都將生成到迭代器中。

>>> from itertools import dropwhile
>>> def iseven(x):
if x % 2 == 0:
return True
else:
return False
>>> list(dropwhile(iseven, [12,90,61,4,15]))
[61, 4, 15]

filterfalse() − 此函式透過過濾掉謂詞函式結果為 False 的元素返回一個迭代器。

>>> from itertools import filterfalse
>>> def iseven(x):
if x % 2 == 0:
return True
else:
return False
>>> list(filterfalse(iseven, [12,90,61,4,15]))
[61, 15]

islice() − 此函式透過從可迭代物件中選擇某些元素來構建迭代器。選擇標準取決於 start、stop 和 step 引數。選擇從 start 值開始,一直持續到 stop 值。如果 stop 為 None,則一直到可迭代物件的末尾,否則選擇在指定的索引處停止。step 引數預設為 1。元素的選擇按 step 引數遞增。所有引數都不能為負數。

>>> from itertools import islice
>>> list(islice(range(10),1,5,2))
[1, 3]
>>> list(islice(range(10),0,None,3))
[0, 3, 6, 9]
>>> list(islice(range(10),5,None))
[5, 6, 7, 8, 9]
>>> list(islice(range(10),5))
[0, 1, 2, 3, 4]

以下函式從可迭代物件生成組合迭代器。

product() − 此函式生成一個迭代器,它是輸入序列中元素的笛卡爾積。這相當於構建巢狀的 for 迴圈,每個迴圈遍歷一個可迭代序列。

在以下示例中,列表推導式技術用於對兩個序列執行兩個巢狀迴圈以構建笛卡爾積。

>>> [[x,y] for x in [1,2,3] for y in ['a','b','c']]
[[1, 'a'], [1, 'b'], [1, 'c'], [2, 'a'], [2, 'b'], [2, 'c'], [3, 'a'], [3, 'b'], [3, 'c']]

product() 函式產生類似的結果。

>>> from itertools import product
>>> list(product([1,2,3],['a','b','c']))
[(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), (3, 'a'), (3, 'b'), (3, 'c')]

permutations() − 此函式生成輸入可迭代物件中元素的所有可能的排列。每個排列的長度可以作為此函式的第二個引數指定。如果未指定,則長度為 1。

>>> list(permutations(range(1,4),2))
[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]

combinations() − 此函式生成輸入可迭代物件中元素的所有可能的組合。每個排列的長度可以作為此函式的第二個引數指定。如果未指定,則長度為 1。

>>> from itertools import combinations
>>> list(combinations(range(1,4),2))
[(1, 2), (1, 3), (2, 3)]

本文介紹了 Python 庫的 itertools 模組中定義的各種迭代器工具。

更新於: 2019年7月30日

201 次檢視

啟動您的 職業生涯

透過完成課程獲得認證

開始
廣告