2009-11-02 20 views
478

Mam dwa iterables w Pythonie, i chcę, aby przejść nad nimi w parach:Jak równolegle przeglądać dwie listy?

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

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

To powinno skutkować:

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

Jeden sposób, aby zrobić to iteracyjne nad indeksy:

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

Ale wydaje mi się to trochę nieprymetyczne. Czy istnieje lepszy sposób na zrobienie tego?

Odpowiedz

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

zip zatrzymuje się, gdy krótszy foo lub bar przystankami.

W Python 2, zip zwraca listę krotek. To jest w porządku, gdy foo i bar nie są masywne. Jeśli są one masywne, utworzenie zip(foo,bar) jest niepotrzebnie masywną zmienną tymczasową i powinno być zastąpione przez itertools.izip lub itertools.izip_longest, która zwraca iterator zamiast listy.

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 zatrzymuje się, gdy albo foo lub bar jest wyczerpana. izip_longest zatrzymuje się po wyczerpaniu obu foo i bar. Gdy krótszy iterator (y) są wyczerpane, izip_longest daje krotkę z None w pozycji odpowiadającej temu iteratorowi. Możesz także ustawić inny fillvalue oprócz None, jeśli chcesz. Zobacz tutaj dla full story.

W Pythonie 3, zip Zwraca iteratorem krotki jak itertools.izip w python2. Aby uzyskać listę krotek, użyj . Aby zamakać, aż oba moduły będą wyczerpane, należy użyć itertools.zip_longest.


Należy również zauważyć, że zip i jego zip -jak brethen może przyjąć dowolną liczbę iterables jako argumenty.Na przykład,

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

drukuje

1 red manchego 
2 blue stilton 
3 green brie 
+3

@unutbu W Pythonie 3 nazwa funkcji to 'itertools.zip_longest', zamiast' itertools.izip_longest' (w zasadzie 'zip ...' zamiast 'izip ...' w module 'itertools'). Jest to edycja jednoznakowa, w przeciwnym razie sam edytowałbym bardzo małą korektę w twojej odpowiedzi. –

+1

@MichaelA: Dzięki za poprawkę. – unutbu

+0

@unutbu Dlaczego miałbym preferować metodę OP na 'izip'u (nawet jeśli' izip'/'zip' wygląda znacznie czystiej)? – armundle

33

Chcesz funkcję zip.

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

Przed Python 3.0, którą chcesz użyć 'itertools.izip' jeśli masz dużą liczbę elementów. –

9

To, czego szukasz, to zip.

11

Wbudowany zip robi dokładnie to, co chcesz. Jeśli chcesz tego samego zamiast iterables zamiast list, możesz spojrzeć na itertools.izip, które robi to samo, ale daje wyniki po jednym na raz.

2

funkcja zip rozwiązuje problem
Dokumenty: ZIP Library function

cel: umieścić stroną wyjściową siebie Problem:

#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" 

Wyjście:
review1
review2
review3
date1
date2
date3

Rozwiązanie:

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

wyjściowa:
review1: date1
review2: date2
review3: date3

4

Należy użyć funkcji "zip". Oto przykład jak własną funkcję zip może wyglądać

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

Czy chciałbyś pomóc w walce z błędnym przekonaniem, że StackOveflow jest darmową usługą kodowania? Następnie prosimy o uzupełnienie odpowiedzi na podstawie kodu tylko z kilkoma wyjaśnieniami. – Yunnosch

+0

czy to moja odpowiedź jest właściwa? –

+0

co jest nie tak w mojej odpowiedzi.? –