2009-11-02 37 views
478

Tengo dos iterables en Python, y yo quiero ir más de dos en dos:¿Cómo iterar a través de dos listas en paralelo?

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

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

Se debería resultar en:

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

Una manera de hacerlo es iterar sobre la índices:

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

Pero eso me parece un poco antipático. Hay una mejor manera de hacerlo?

Respuesta

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

zip se detiene cuando el más corto de foo o bar paradas.

En Python 2, zip devuelve una lista de tuplas. Esto está bien cuando foo y bar no son masivos. Si ambos son masivos entonces formando zip(foo,bar) es una variable temporal innecesariamente masiva , y debe ser reemplazada por itertools.izip o itertools.izip_longest, que devuelve un iterador en lugar de una lista.

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 paradas cuando se agota cualquiera foo o bar. izip_longest se detiene cuando se agotan foo y bar. Cuando los iteradores más cortos están agotados, izip_longest produce una tupla con None en la posición correspondiente a ese iterador. También puede configurar un fillvalue diferente además de None si lo desea. Vea aquí para el full story.

En Python 3, zip devuelve un iterador de tuplas, como itertools.izip en python2. Para obtener una lista de tuplas, use list(zip(foo, bar)). Y para comprimir hasta que ambos iteradores estén agotados , usaría itertools.zip_longest.


Nótese también que zip y sus zip -como brethen puede aceptar un número arbitrario de iterables como argumentos.Por ejemplo,

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

impresiones

1 red manchego 
2 blue stilton 
3 green brie 
+3

@unutbu En Python 3, el nombre de la función es 'itertools.zip_longest', en lugar de' itertools.izip_longest' (básicamente 'zip ...' en lugar de 'izip ...' en el módulo 'itertools'). Es una edición de un solo personaje; de ​​lo contrario, editaría la corrección súper menor en tu respuesta yo mismo. –

+1

@MichaelA: Gracias por la corrección. – unutbu

+0

@unutbu ¿Por qué preferiría el método de OP sobre el de 'izip' (aunque el' izip'/'zip' se vea mucho más limpio)? – armundle

33

Desea la función zip.

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

Antes de Python 3.0 que te gustaría usar 'itertools.izip' si tiene un gran número de elementos. –

9

Lo que estás buscando se llama zip.

11

El builtin zip hace exactamente lo que quiere. Si desea el mismo sobre iterables en lugar de listas, puede mirar itertools.izip, que hace lo mismo pero da resultados de uno en uno.

2

función postal resuelve el problema
Docs: ZIP Library function

objetivo: poner el lado de salida al lado del otro Problema:

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

Salida:
Review1
review2
revisión3
fecha1
la fecha 2
fecha3

Solución:

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

Salida:
Review1: fecha1
review2: la fecha 2
review3: date3

4

Debe utilizar la función 'zip'. Aquí hay un ejemplo de cómo su propia función postal puede parecer

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

¿Te gustaría ayudar a luchar contra la idea errónea de que StackOveflow es un servicio gratuito de codificación? Luego, por favor, aumente su respuesta de solo código con alguna explicación. – Yunnosch

+0

es esta mi respuesta es ¿verdad? –

+0

¿Qué hay de malo en mi respuesta? –

Cuestiones relacionadas