I've had people try to explain why Python's generators are deficient before and the light just went off. To flatten an arbitrarily deep (though stack-limited) nested iterator structure, I wrote:
>>> def flatten(iterable): ... for elem in iterable: ... if hasattr(elem, '__iter__'): ... for sub in flatten(elem): yield sub ... else: ... yield elem ... >>> list(flatten([[1,2,3],[[2,3],4],[4,5,6]])) [1, 2, 3, 2, 3, 4, 4, 5, 6]
The key failing is that inner "for" loop. It's called "trampolining" as described by David Beazley. If I could somehow yield to the top of the generator stack it'd be unnecessary. It'd look something like PEP 380:
>>> def flatten(iterable): ... for elem in iterable: ... if hasattr(elem, '__iter__'): ... yield from flatten(elem) ... else: ... yield elem ... >>> list(flatten([[1,2,3],[[2,3],4],[4,5,6]])) [1, 2, 3, 2, 3, 4, 4, 5, 6]
Too bad there's a moratorium on changes :)
Updated to include the PEP, thanks ulrik!