6

Trying to solve my problem using chain from itertools. I have a list of iterators and I want to get an iterator that iterates through items of the iterators in the list in a seamless manner. Is there a way to do so? Perhaps another tool instead of chain would be more suitable?

Simplified example of my code:

iter1 = iter([1,2])
iter2 = iter([3,4])
iter_list = [iter1, iter2]
chained_iter = chain(iter_list)

Desired result:

chained_iter.next() --> 1
chained_iter.next() --> 2
chained_iter.next() --> 3
chained_iter.next() --> 4

Actual result:

chained_iter.next() --> <listiterator at 0x10f374650>
wolf
  • 127
  • 1
  • 10

2 Answers2

10

You want to use itertools.chain.from_iterable() instead:

chained_iter = chain.from_iterable(iter_list)

You passed a single iterable to chain(); it is designed to take the elements from multiple iterables and chain those. It doesn't matter that that single iterable contains more iterators.

You could also apply that list using the * syntax:

chained_iter = chain(*iter_list)

That works fine for a list, but if iter_list was itself an endless iterator, you probably wouldn't want Python to try to expand that into separate arguments.

Demo:

>>> from itertools import chain
>>> iter1 = iter([1, 2])
>>> iter2 = iter([3, 4])
>>> iter_list = [iter1, iter2]
>>> chained_iter = chain.from_iterable(iter_list)
>>> next(chained_iter)
1
>>> next(chained_iter)
2
>>> next(chained_iter)
3
>>> next(chained_iter)
4
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
1

You can try this way :

>>> from itertools import chain
>>> iter1 = iter([1,2])
>>> iter2 = iter([3,4])
>>> iter_list = [iter1, iter2]
>>> chained_iter = chain(*iter_list)
>>> next(chained_iter)
1
>>> next(chained_iter)
2
>>> next(chained_iter)
3
>>> next(chained_iter)
4
>>>
Md. Rezwanul Haque
  • 2,882
  • 7
  • 28
  • 45