Python: Función para aplanar el generador que contiene otro generador.

Me gustaría saber cómo escribir la función python que puede aplanar el generador que produce otros generadores o iteables (que también puede producir otros generadores / iterables … posiblemente infinitamente).

Aquí está el ejemplo:

gen(gen(1,2,3), gen(4,5,6), [7,8,9], [gen(10,11,12), gen(13,14,15)])

nota: gen – significa objeto generador, el contenido entre paréntesis después de gen es información que generará gen .

El resultado esperado después de “aplanamiento”: gen(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)

¡Es necesario que la función de aplanamiento también devuelva el generador! (porque de lo contrario, el uso anterior de los generadores no tendría sentido).

Solo para tener en cuenta, estoy usando python 3.

¡Gracias!

La forma más fácil es una función de aplanamiento recursivo. Suponiendo que desea descender a todos los iterables excepto las cadenas, podría hacer esto:

 def flatten(it): for x in it: if (isinstance(x, collections.Iterable) and not isinstance(x, str)): for y in flatten(x): yield y else: yield x 

A partir de Python 3.3, también puede escribir

 def flatten(it): for x in it: if (isinstance(x, collections.Iterable) and not isinstance(x, str)): yield from flatten(x) else: yield x 

El método no recursivo es esencialmente un desenrollado del método recursivo, utilizando una stack:

 def flatten(it): stack = [] it = iter(it) while True: try: x = next(it) except StopIteration: if stack: it = stack.pop() continue else: return if isinstance(x, collections.Iterable) and not isinstance(x, str): stack.append(it) it = iter(x) else: yield x