如何使用 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]
使用列表推导,我可以通过指定表达式和要循环的输入序列来实现相同的结果。
# 列表推导
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. 创建数字列表
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"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 内置函数的行为会很奇怪。让我们尝试一下。
# 向列表添加一个新数字
list1.append(1000)
print(f"Output \n*** Length of List1 is {len(list1)} , Length of List2 is {len(list2)}")
# 对列表运行 zip 进行添加。
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 时非常小心。
在 itertools 的 python 函数中,您可以找到一个解决此问题的选项,称为 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。
相关文章
有用资源
python 参考教程 - 该教程包含有关 python 的更多信息:https://www.cainiaomax.com/python/

