views:

623

answers:

2

Suppose we have an iterator (an infinite one) that returns lists (or finite iterators), for example one returned by

infinite = itertools.cycle([[1,2,3]])

What is a good Python idiom to get an iterator (obviously infinite) that will return each of the elements from the first iterator, then each from the second one, etc. In the example above it would return 1,2,3,1,2,3,.... The iterator is infinite, so itertools.chain(*infinite) will not work.

Related

+3  A: 

Use a generator:

(item for it in infinite for item in it)

The * construct unpacks into a tuple in order to pass the arguments, so there's no way to use it.

Thomas Wouters
+13  A: 
def flatten(iterables):
    return (elem for iterable in iterables for elem in iterable)

Edit: Starting with Python 2.6, you can also say

itertools.chain.from_iterable(iterables)
Torsten Marek
@JF: Unfortunately, no - the iterator is infinite, so Python will exhaust memory trying to expand the *iterables expression.
Rafał Dowgird
@Rafal Dowgird: My mistake. I should have read the question title.
J.F. Sebastian
I really like the second one, with chain. "for blah in bloop for blech in blerp" is smelly, IMHO.
Warren P