Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chaining Iterators To Flat Iterator

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>
like image 451
wolf Avatar asked Aug 02 '17 07:08

wolf


People also ask

Are iterators faster than for loops Python?

That being said, the iterators from itertools are often significantly faster than regular iteration from a standard Python for loop.

Can iterators go backwards?

A reverse iterator is a kind of iterator, that travels in backwards direction. It means when we increment a reverse_iterator, it goes to the previous element in container. So, to iterate over a vector in reverse direction, we can use the reverse_iterator to iterate from end to start.

What is Islice?

islice (iterable, start, stop[, step]) Make an iterator that returns selected elements from the iterable. If start is non-zero, then elements from the iterable are skipped until start is reached. Afterward, elements are returned consecutively unless step is set higher than one which results in items being skipped.

What is iteration in Python explain ITER () and next method ()?

An iterator is an object that contains a countable number of values. An iterator is an object that can be iterated upon, meaning that you can traverse through all the values. Technically, in Python, an iterator is an object which implements the iterator protocol, which consist of the methods __iter__() and __next__() .


1 Answers

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
like image 163
Martijn Pieters Avatar answered Nov 02 '22 03:11

Martijn Pieters