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

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])

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


当前回答

Python 3

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

当较短的foo或bar停止时,Zip停止。

在Python 3中,zip 返回元组的迭代器,如itertools。Python2中的izip。得到一份清单 对于元组,使用list(zip(foo, bar))。和压缩,直到两个迭代器都为 累了,你会用 itertools.zip_longest。

Python 2

在Python 2中,zip 返回一个元组列表。当foo和bar不是巨大的时候,这很好。如果它们都是巨大的,那么形成zip(foo,bar)是不必要的巨大 临时变量,应由itertools替换。izip或 itertools。Izip_longest,它返回一个迭代器而不是一个列表。

import itertools
for f,b in itertools.izip(foo,bar):
    print(f,b)
for f,b in itertools.izip_longest(foo,bar):
    print(f,b)

当foo或bar耗尽时,Izip停止。 当foo和bar耗尽时,Izip_longest停止。 当较短的迭代器耗尽时,izip_longest将在该迭代器对应的位置生成一个具有None的元组。如果你愿意,你也可以设置一个不同的填充值。请看这里了解完整的故事。


还要注意,zip及其类似zip的兄弟可以接受任意数量的可迭代对象作为参数。例如,

for num, cheese, color in zip([1,2,3], ['manchego', 'stilton', 'brie'], 
                              ['red', 'blue', 'green']):
    print('{} {} {}'.format(num, color, cheese))

打印

1 red manchego
2 blue stilton
3 green brie

其他回答

你需要zip函数。

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

我们可以使用索引来迭代…

foo = ['a', 'b', 'c']
bar = [10, 20, 30]
for indx, itm in enumerate(foo):
    print (foo[indx], bar[indx])

Python 3

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

当较短的foo或bar停止时,Zip停止。

在Python 3中,zip 返回元组的迭代器,如itertools。Python2中的izip。得到一份清单 对于元组,使用list(zip(foo, bar))。和压缩,直到两个迭代器都为 累了,你会用 itertools.zip_longest。

Python 2

在Python 2中,zip 返回一个元组列表。当foo和bar不是巨大的时候,这很好。如果它们都是巨大的,那么形成zip(foo,bar)是不必要的巨大 临时变量,应由itertools替换。izip或 itertools。Izip_longest,它返回一个迭代器而不是一个列表。

import itertools
for f,b in itertools.izip(foo,bar):
    print(f,b)
for f,b in itertools.izip_longest(foo,bar):
    print(f,b)

当foo或bar耗尽时,Izip停止。 当foo和bar耗尽时,Izip_longest停止。 当较短的迭代器耗尽时,izip_longest将在该迭代器对应的位置生成一个具有None的元组。如果你愿意,你也可以设置一个不同的填充值。请看这里了解完整的故事。


还要注意,zip及其类似zip的兄弟可以接受任意数量的可迭代对象作为参数。例如,

for num, cheese, color in zip([1,2,3], ['manchego', 'stilton', 'brie'], 
                              ['red', 'blue', 'green']):
    print('{} {} {}'.format(num, color, cheese))

打印

1 red manchego
2 blue stilton
3 green brie

您可以使用推导式将第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