有没有一种方法可以实现并行的for-each循环?

11

假设我在Python中有两个列表,我想并行遍历每个列表——例如,在两个列表的元素1上执行某些操作,然后在两个列表的元素2上执行某些操作... 我知道可以通过使用索引来实现这一点:

for listIndex in range(len(list1)):
   doSomething(list1[listIndex])
   doSomething(list2[listIndex])

但是有没有更直观的方法,使用foreach循环来完成呢?类似于 for list1Value in list1, list2Value in list2 ...?

我目前在Python中遇到了这种情况,但这是一个长期存在的问题,如果您知道任何语言可以解决这个问题,我会很感兴趣。 (我只是假设Python最有可能有一种处理这种情况的方法。)

3个回答

14

像这样吗?

for (a,b) in zip(list1, list2):
  doSomething(a)
  doSomething(b)

虽然如果doSomething()不涉及I/O或更新全局状态,并且它只是逐个处理元素,则顺序无关紧要,因此您可以使用chain()(来自itertools):

for x in chain(list1, list2):
  doSomething(x)

顺便说一下,我经常使用from itertools import *。请考虑使用izip()而不是我上面给出的zip()。还可以查看izip_longest()izip(count(), lst)等内容。欢迎来到函数式编程的世界。 :-)

哦,而且压缩也适用于更多“列”:

for idx, a, b, c in izip(count(), A, B, C):
  ...

一个没有全局性和适用性的链式编程的例子:for item1, item2 in zip(iter1, iter2): fileobj.write("%s %s\n" % (item1, item2)) - tzot
谢谢,这很棒!只有一个快速的问题...这个方法需要列表长度相同吗?如果它们不同会发生什么? - froadie
1
它会在较短的列表用尽时立即停止。 - Tim Pietzcker
@froadie,您可以使用izip_longest()函数来“填充”最短的列表,并使用默认值(默认为None)进行填充。同时,回答也进行了一些更新。 - integer
第二个例子,它不应该是 doSomething(x) 吗? - Javier

5

这将取决于编程语言。Python实际上有一个非常简单的方法:

a = (0,1,2,3,4,5,6,7,8,9)
b = "ABCDEFGHIJ"
for pair in zip(a,b):
  print("%d => %s" % pair)

4
使用 zipitertools.izip 来实现此功能:
for item1, item2 in zip(iterable1, iterable2):
    # process the items in parallel

Python中的itertools.izip(在Python < 3中)和zip(在Python ≥ 3中)返回迭代器,即它们根据请求提供一对元组(或三元组、四元组等)。Python < 3的zip创建一个元组列表,因此如果最小的序列非常长,则内存需求可能很大。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接