如何使用ZIP並行處理迭代器


介紹

列表推導式使從源列表獲取派生列表並應用表示式變得容易。例如,假設我想將列表中的每個元素乘以5。在這裡,我使用簡單的for迴圈來實現。

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
multiply_by_5 = []
for x in a:
multiply_by_5.append(x*5)
print(f"Output \n *** {multiply_by_5}")

輸出

*** [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]

使用列表推導式,我可以透過指定表示式和要迴圈遍歷的輸入序列來獲得相同的結果。

# List comprehension
multiply_by_5 = [x*2 for x in a]
print(f"Output \n *** {multiply_by_5}")

輸出

*** [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

現在,假設您有兩個列表需要相加。

# 1 . Create a List of Numbers
list1 = [100, 200, 300, 400]
list2 = [500, 600, 700, 800]

# 2. Add the two lists to create a new list
list3 = []

# Using a Loop.
for i in range(len(list1)):
added_value = list1[i] + list2[i]
list3.append(added_value)
print(f"Output \n*** {list3}")

輸出

*** [600, 800, 1000, 1200]

現在,這裡重要的是,派生列表(在本例中為list3)中新增的值與源列表中的項透過其索引直接相關。

現在,就壓縮而言,這是針對相同列表整數的壓縮解決方案。在這種情況下,兩個整數列表,一個包含100、200、300和400,另一個包含500、600、700和800。當然,我們可以定義它們並將它們賦給變數。它們不必是列表。

它們可以是其他序列,例如元組等等。

因此,我們將要做的就是將這些元素對從列表中壓縮在一起,因此list1中的100和list2中的500將被壓縮在一起,依此類推。對於每個元組,當我們遍歷它們時,我們將把元組解包到變數a和b中。

list4 = []
list4 = [(a + b) for a, b in zip(list1, list2)]
print(f"Output \n*** {list4}")

輸出

*** [600, 800, 1000, 1200]

上面的解決方案看起來很酷,但是在你將它們應用到你的程式碼中之前,你需要知道一個嚴重的問題。

如果輸入迭代器的長度不同,內建函式zip的行為很奇怪。讓我們嘗試一下。

# add a new number to the list
list1.append(1000)
print(f"Output \n*** Length of List1 is {len(list1)} , Length of List2 is {len(list2)}")

# run the zip against the list for addition.
list5 = [(a + b) for a, b in zip(list1, list2)]
print(f"*** {list5}")

輸出

*** Length of List1 is 9 , Length of List2 is 4
*** [600, 800, 1000, 1200]

現在,當我們打印出list3中的每個新增的數字時,你會注意到新增到list1的數字不見了,即使我們把它新增到那裡,它也在list1中,但在zip的輸出中卻沒有顯示。

這就是zip的工作方式。它會讓你保持在元組中,直到任何一個迭代器用盡。因此,即使list1比list2還有更多內容,它也會先用盡,然後迴圈退出。

令人驚訝的是,你不會收到任何異常通知。因此,在生產環境中必須非常小心使用zip。

在python函式中,你有一個來自itertools的選項,叫做zip_longest。

zip_longest的作用是,即使其中一個迭代器用盡了,它也會繼續。

from itertools import zip_longest

list6 = []
for a, b in zip_longest(list1, list2):
if b is None:
print(f" << do your logic here >> ")
elif a is None:
print(f" << do your logic here >> ")
else:
list6.append(a + b)
print(f"Output \n*** {list6}")


<< do your logic here >>
<< do your logic here >>
<< do your logic here >>
<< do your logic here >>
<< do your logic here >>

輸出

*** [600, 800, 1000, 1200]

結論

  • 如果你想並行迭代多個迭代器,zip函式非常方便。

  • 當傳遞不同長度的迭代器時,zip函式的工作方式不同。

  • 如果你想使用不同長度的迭代器,那麼使用zip_longest。

更新於:2020年11月9日

281 次瀏覽

開啟你的職業生涯

完成課程獲得認證

開始學習
廣告