2010-07-12 35 views
11

Digamos que tengo 2 listas en Python y quiero recorrerlas en paralelo, p. Ej. hacer algo con el elemento 1 para ambas listas, hacer algo con el elemento 2 para ambas listas ... Sé que puedo hacer esto mediante el uso de un índice:¿Hay alguna manera de tener paralelo para cada bucle?

for listIndex in range(len(list1)): 
    doSomething(list1[listIndex]) 
    doSomething(list2[listIndex]) 

Pero hay una manera de hacer esto de forma más intuitiva, con un bucle Foreach? Algo así como for list1Value in list1, list2Value in list2 ...?

Actualmente me encuentro con esta situación en Python, pero esta es una pregunta de larga data y me gustaría saber si puede hacerlo en cualquier idioma. (Acabo de suponer que Python es el más propenso a tener un método para tratar con esto.)

Respuesta

14

¿Algo como esto?

for (a,b) in zip(list1, list2): 
    doSomething(a) 
    doSomething(b) 

Aunque si doSomething() no está haciendo E/S o la actualización de estado global, y que sólo funciona en uno de los elementos a la vez, el orden no importa lo que sólo podría utilizar chain() (de itertools):

for x in chain(list1, list2): 
    doSomething(x) 

A propósito, from itertools import * es algo que hago muy a menudo. Considere izip() en lugar de usar el zip() que di más arriba. Consulte también izip_longest(), izip(count(), lst), etc. Bienvenido a la programación funcional. :-)

Ah, y comprimir también trabaja con "columnas" más:

for idx, a, b, c in izip(count(), A, B, C): 
    ... 
+0

+1 para 'itertool.chain()'! – EOL

+0

un ejemplo de no globalidad y no aplicabilidad de cadena: 'para item1, item2 en zip (iter1, iter2): fileobj.write ("% s% s \ n "% (item1, item2))' – tzot

+0

gracias esto es genial ! solo una pregunta rápida ... ¿requiere este método que las listas tengan la misma longitud? ¿Qué pasa si no lo son? – froadie

4

que dependerá de la lengua. Python tiene en realidad un método bastante sencillo para que:

a = (0,1,2,3,4,5,6,7,8,9) 
b = "ABCDEFGHIJ" 
for pair in zip(a,b): 
    print("%d => %s" % pair) 
4

Uso zip o itertools.izip para esto:

for item1, item2 in zip(iterable1, iterable2): 
    # process the items in parallel 

itertools.izip en Python < 3 y zip en Python ≥ 3 iteradores de retorno; es decir, proporcionan tuplas de pares (o trillizos, cuartetos, etc.) a petición. Python crea una lista de tuplas, por lo que los requisitos de memoria pueden ser grandes si la secuencia más pequeña es bastante larga.

+0

zip parece funcionar en Python 2.6 así – froadie

+0

@froadie: Nunca dije que no funciona. – tzot

Cuestiones relacionadas