2009-11-02 85 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