如何使用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。