Tengo dos generadores que dicen A()
y B()
. Quiero recorrer ambos generadores juntos. Algo como:
for a,b in A(),B(): # I know this is wrong #do processing on a and b
Una forma es almacenar los resultados de ambas funciones en las listas y luego recorrer la lista fusionada. Algo como esto:
resA = [a for a in A()] resB = [b for b in B()] for a,b in zip(resA, resB): #do stuff
Si se está preguntando, entonces sí, ambas funciones producen igual número de valor.
Pero no puedo usar este enfoque porque A()/B()
devuelve tantos valores. Almacenarlos en una lista agotaría la memoria, por eso uso generadores.
¿Hay alguna manera de pasar por encima de ambos generadores a la vez?
Estabas casi allí. En Python 3, simplemente pase los generadores a zip()
:
for a, b in zip(A(), B()):
zip()
toma cualquier iterable, no solo listas. Se consumirán los generadores uno por uno.
En Python 2, usa itertools.izip()
:
from itertools import izip for a, b in izip(A(), B()):
Además, convertir un generador en una lista es tan simple como una list(generator)
; No hay necesidad de usar una lista de comprensión allí.
Suena como lo quieres itertools.izip
:
from itertools import izip for a, b in izip(A(), B()):
De los documentos:
Como
zip()
excepto que devuelve un iterador en lugar de una lista.
De esta manera, nunca creas una list
, ya sea de A()
, B()
o la izip()
.
Tenga en cuenta que en el zip
básico de Python 3 es como itertools.izip
Python 2.x.
Puede usar la función zip para transformar las dos listas generadas en una lista de tuplas, de modo que puede usar la forma que desee:
for a,b in zip(A(), B()): pass