如何使用ZIP并行处理迭代器
阅读更多:Python 教程
简介
列表推导式可通过应用表达式轻松地获取源列表并得到衍生列表。例如,假设我想将列表中的每个元素乘以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"输出 \n *** {multiply_by_5}")
输出
*** [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
通过列表推导式,我可以通过指定表达式和要循环遍历的输入序列来达到相同的结果。
# 列表推导式
multiply_by_5 = [x*2 for x in a]
print(f"输出 \n *** {multiply_by_5}")
输出
*** [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
现在,假设你有一对要加的列表。
#1.创建数字列表
list1 = [100, 200, 300, 400]
list2 = [500, 600, 700, 800]
#2.将两个列表相加以创建新列表
list3 = []
#使用循环。
for i in range(len(list1)):
added_value = list1[i] + list2[i]
list3.append(added_value)
print(f"输出 \n*** {list3}")
输出
*** [600, 800, 1000, 1200]
现在重要的是,衍生列表(我们的情况下是list3)中的项与源列表中的项直接由它们的索引联系在一起。
现在,关于zip,这里是一个相同整数列表的zip解决方案。在这种情况下,有两个整数列表,一个包含100、200、300和400,另一个包含500、600、700和800。当然,我们可以定义它们并将它们分配给变量。它们不必是列表,它们可以是其他序列,比如元组等。
因此,我们将从这些列表中对一对元素进行zip,因此将list1中的100和list2中的500一起压缩,以此类推。对于每个元组,当我们迭代它们时,我们将元组解包到变量a和b中。
list4 = []
list4 = [(a + b) for a, b in zip(list1, list2)]
print(f"输出 \n*** {list4}")
输出
*** [600, 800, 1000, 1200]
现在上面的解决方案看起来真的很酷,但在将它们应用于您的代码之前需要注意一个严重的问题。
如果输入的迭代器长度不同,zip内置函数会表现出奇怪的行为。让我们试试它们。
#将一个新数字添加到列表中
list1.append(1000)
print(f"输出 \n*** List1的长度为{len(list1)},List2的长度为{len(list2)}")
#对列表运行zip以进行加法。
list5 = [(a + b) for a, b in zip(list1, list2)]
print(f"*** {list5}")
输出
*** List1的长度为9,List2的长度为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" << 在此处执行逻辑 >> ")
elif a is None:
print(f" << 在此处执行逻辑 >> ")
else:
list6.append(a + b)
print(f"输出 \n*** {list6}")
<< 在此处执行逻辑 >>
<< 在此处执行逻辑 >>
<< 在此处执行逻辑 >>
<< 在此处执行逻辑 >>
<< 在此处执行逻辑 >>
输出
*** [600, 800, 1000, 1200]
结论:
-
如果您想同时迭代多个迭代器,则 zip 函数非常方便。
-
当您传递不同长度的迭代器时,zip 函数的工作方式不同。
-
如果您想使用不同长度的迭代器,则请使用 zip_longest。