2009-11-02 83 views
478

我有两个iterables在Python,我想去过它们对:如何并行迭代两个列表?

foo = (1, 2, 3) 
bar = (4, 5, 6) 

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

应该导致:

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

一个办法做到这一点是要遍历指数:

for i in xrange(len(foo)): 
    print "f: ", foo[i], "; b: ", b[i] 

但是,这似乎有点unpythonic对我来说。有没有更好的方法来做到这一点?

回答

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

zip停止时的foobar停止越短。

Python 2,zip 返回元组列表。当foobar不是很大时,这很好。如果 它们都很大,那么形成zip(foo,bar)是一个不必要的庞大的 临时变量,应该替换为itertools.izipitertools.izip_longest,它将返回一个迭代器而不是一个列表。当任一或foobar耗尽

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) 

izip停止。当foobar都用尽时, izip_longest停止。 当较短的迭代器耗尽时,izip_longest会在与该迭代器相对应的位置产生一个元组None。如果您愿意,您还可以设置除None之外的其他fillvalue。看到这里的​​。

Python 3中zip 返回的元组的迭代器,像在Python2 itertools.izip。要获取元组的列表 ,请使用list(zip(foo, bar))。并且要压缩,直到两个迭代器都被耗尽,您将使用 itertools.zip_longest


还要注意zip及其zip样brethen可以接受iterables作为参数的任意数量。例如,

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 
+3

@unutbu在Python 3中,函数名是'itertools.zip_longest',而不是'itertools.izip_longest'(基本上'zip ...'而不是'itertools'模块中的'izip ...')。这是一个单独的字符编辑,否则我会自己编辑超级小调整到你的答案中。 – 2014-10-15 20:04:21

+1

@MichaelA:感谢您的纠正。 – unutbu 2014-10-15 20:25:11

+0

@unutbu为什么我会更喜欢OP的方法而不是'izip'(即使'izip' /'zip'看起来更干净)? – armundle 2016-03-14 19:23:08

33

您需要zip函数。

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

的Python 3.0之前,你会想,如果你有大量的元素使用'itertools.izip'。 – 2009-11-02 21:35:13

9

你在找什么叫做zip

11

内建的zip完全符合你的要求。如果你想要迭代而不是列表,你可以看看itertools.izip,它可以做同样的事情,但一次给出一个结果。

2

拉链功能解决了这个问题
文档:ZIP Library function

目的:通过侧放输出端 问题:

#value1 is a list 
value1 = driver.find_elements_by_class_name("review-text") 
#value2 is a list 
value2 = driver.find_elements_by_class_name("review-date") 

for val1 in value1: 
    print(val1.text) 
    print "\n" 
for val2 in value2: 
    print(val2.text) 
    print "\n" 

输出:
review1
review2
review3
DATE1
DATE2
DATE3

解决方案:

for val1, val2 in zip(value1,value2): 
    print (val1.text+':'+val2.text) 
    print "\n" 

输出:
review1:DATE1
review2:DATE2
review3:date3

4

您应该使用'zip'功能。下面是一个例子你自己的压缩功能,可看怎么样

def custom_zip(seq1, seq2): 
    it1 = iter(seq1) 
    it2 = iter(seq2) 
    while True: 
     yield next(it1), next(it2) 
-1
def ncustom_zip(seq1,seq2,max_length): 
     length= len(seq1) if len(seq1)>len(seq2) else len(seq2) if max_length else len(seq1) if len(seq1)<len(seq2) else len(seq2) 
     for i in range(length): 
       x= seq1[i] if len(seq1)>i else None 
       y= seq2[i] if len(seq2)>i else None 
       yield x,y 


l=[12,2,3,9] 
p=[89,8,92,5,7] 

for i,j in ncustom_zip(l,p,True): 
     print i,j 
for i,j in ncustom_zip(l,p,False): 
     print i,j 
+1

你想帮助打击StackOveflow是一个免费编码服务的误解吗?然后请用一些解释来补充您的仅用于代码的答案。 – Yunnosch 2017-12-24 14:06:04

+0

这是我的回答是对的吗? – 2017-12-24 14:09:22

+0

我的答案有什么问题? – 2017-12-25 05:12:02