Quiero cambiar el siguiente código
for directory, dirs, files in os.walk(directory_1):
do_something()
for directory, dirs, files in os.walk(directory_2):
do_something()
a este código:
for directory, dirs, files in os.walk(directory_1) + os.walk(directory_2):
do_something()
Me sale el error:
tipos de operandos no admitidos para +: 'generador' y 'generador'
¿Cómo unir dos generadores en Python?
Respuestas:
Creo que
itertools.chain()
debería hacerlo.fuente
itertools.chain()
no devuelve unatypes.GeneratorType
instancia. Por si acaso el tipo exacto es crucial.Un ejemplo de código:
fuente
itertools.chain()
respuesta ya altamente votada ?En Python (3.5 o superior) puedes hacer:
fuente
def chain(*iterables): for iterable in iterables: yield from iterable
(Ponga eldef
yfor
en líneas separadas cuando lo ejecute.)a
se verifica hasta que todo se obtiene de él, incluso sib
no es un iterador. ElTypeError
porb
no ser un iterador aparecerá más tarde.Ejemplo simple:
fuente
itertools.chain()
respuesta ya altamente votada ?itertools.chain
devuelve un iterador, no un generador.chain([1, 2, 3], [3, 4, 5])
?Con itertools.chain.from_iterable puedes hacer cosas como:
fuente
genny
cuando ya devuelve un generador.list(itertools.chain.from_iterable(genny(x)))
Es mucho más conciso.list
constructor es mucho más legible que la comprensión de la lista. Su método es mucho más ilegible en ese sentido.Aquí está usando una expresión generadora con
for
s anidado :fuente
También se puede usar el operador de desempaquetado
*
:NOTA: Funciona de manera más eficiente para iterables 'no perezosos'. También se puede usar con diferentes tipos de comprensión. La forma preferida para el generador de concat sería de la respuesta de @Uduse
fuente
Si desea mantener los generadores separados pero aún iterar sobre ellos al mismo tiempo, puede usar zip ():
NOTA: La iteración se detiene en el más corto de los dos generadores.
Por ejemplo:
fuente
Digamos que tenemos que generar (gen1 y gen 2) y queremos realizar algún cálculo adicional que requiera el resultado de ambos. Podemos devolver el resultado de dicha función / cálculo a través del método de mapa, que a su vez devuelve un generador que podemos recorrer.
En este escenario, la función / cálculo debe implementarse mediante la función lambda. La parte difícil es lo que pretendemos hacer dentro del mapa y su función lambda.
Forma general de solución propuesta:
fuente
Todas esas soluciones complicadas ...
solo haz:
Si realmente quiere "unir" ambos generadores, haga lo siguiente:
fuente
Yo diría que, como se sugiere en los comentarios del usuario "wjandrea", la mejor solución es
No cambia el tipo devuelto y es realmente pitónico.
fuente