我有两个可迭代对象,我想成对地遍历它们:

foo = [1, 2, 3]
bar = [4, 5, 6]

for (f, b) in iterate_together(foo, bar):
    print("f:", f, " |  b:", b)

这将导致:

f: 1  |  b: 4
f: 2  |  b: 5
f: 3  |  b: 6

一种方法是遍历索引:

for i in range(len(foo)):
    print("f:", foo[i], " |  b:", bar[i])

但对我来说,这似乎有点荒唐。有更好的办法吗?


当前回答

你需要zip函数。

for (f,b) in zip(foo, bar):
    print "f: ", f ,"; b: ", b

其他回答

下面是如何使用列表推导式:

a = (1, 2, 3)
b = (4, 5, 6)
[print('f:', i, '; b', j) for i, j in zip(a, b)]

它打印:

f: 1 ; b 4
f: 2 ; b 5
f: 3 ; b 6

你需要zip函数。

for (f,b) in zip(foo, bar):
    print "f: ", f ,"; b: ", b

您可以使用推导式将第n个元素捆绑到元组或列表中,然后使用生成器函数将它们传递出去。

def iterate_multi(*lists):
    for i in range(min(map(len,lists))):
        yield tuple(l[i] for l in lists)

for l1, l2, l3 in iterate_multi([1,2,3],[4,5,6],[7,8,9]):
    print(str(l1)+","+str(l2)+","+str(l3))

如果你想在使用zip()遍历多个列表时保留下标,你可以将zip对象传递给enumerate():

for i, (f, b) in enumerate(zip(foo, bar)):
    # do something

例如,如果你想打印出两个列表中值不同的位置,你可以这样做。

foo, bar = ['a', 'b', 'c'], ['a', 'a', 'c']

for i, (f, b) in enumerate(zip(foo, bar)):
    if f != b:
        print(f"items at index {i} are different")
    
# items at index 1 are different

如果您的列表没有相同的长度,则zip()迭代直到最短的列表结束。如果希望迭代到最长的列表结束,请使用内置itertools模块中的zip_longest。默认情况下,它会用None填充缺失的值(但是您可以使用fillvalue参数将其更改为任何您想要的值)。

from itertools import zip_longest
for f, b in zip_longest(foo, bar):
    # do something

你应该使用'zip'函数。下面是您自己的zip函数的示例

def custom_zip(seq1, seq2):
    it1 = iter(seq1)
    it2 = iter(seq2)
    while True:
        yield next(it1), next(it2)