Python: smoothing function of a generator containing another generator

I would like to know how to write a python function that can smooth out a generator that gives other generators or iteables (which can also lead to other generators / iterators ... possibly endlessly).

Here is an example:

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

note: gen - means a generator object, the contents between parentheses after gen are the data that will generate gen yield.

Expected result after smoothing: gen(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)

The flatten function must also return a generator! (since otherwise the previous use of generators would be pointless).

Just note that I'm using python 3.

Thanks!

+8
python generator
source share
2 answers

The easiest way is a recursive smoothing function. Assuming you want to go down to every iterable, except for the lines, you can do this:

 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 

Starting with Python 3.3, you can also write

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

A non-recursive method is essentially the deployment of a recursive method using the 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 
0
source share

All Articles