Python tutorials > Advanced Python Concepts > Iterators and Generators > How to chain iterators?
How to chain iterators?
itertools.chain()
function. Chaining iterators allows you to treat a sequence of iterables as a single, unified iterator, simplifying your code and improving readability, especially when dealing with large datasets or dynamically generated sequences.
Introduction to Iterator Chaining
itertools
module provides powerful tools for working with iterators, including the chain()
function which is specifically designed for this purpose.
Basic Example using itertools.chain()
itertools.chain()
. We create three lists, list1
, list2
, and list3
. We then pass these lists as arguments to itertools.chain()
, which returns an iterator that will yield elements from list1
, then list2
, and finally list3
. The loop iterates through this chained iterator, printing each element. Notice that the original lists are not modified, and no new list is created in memory to hold all the elements.
import itertools
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list3 = [7, 8, 9]
chained_iterator = itertools.chain(list1, list2, list3)
for item in chained_iterator:
print(item)
Chaining Different Iterable Types
itertools.chain()
can handle different iterable types (lists, tuples, sets, strings, etc.) as arguments. This example shows how to chain a list, a tuple, and a set into a single iterator. The output will iterate through the elements of each iterable in the order they were passed to chain()
. Note that the order of elements from a set might not be the same as the order they were inserted.
import itertools
my_list = [1, 2, 3]
my_tuple = (4, 5, 6)
my_set = {7, 8, 9}
chained_iterator = itertools.chain(my_list, my_tuple, my_set)
for item in chained_iterator:
print(item)
Chaining from a List of Iterables
itertools.chain.from_iterable()
. This method takes a single iterable as input, where each element of that iterable is itself an iterable. It effectively flattens the structure by chaining the inner iterables together. This approach avoids unpacking the iterables manually, which can be less readable and more error-prone.
import itertools
list_of_iterables = [[1, 2], (3, 4), {5, 6}]
chained_iterator = itertools.chain.from_iterable(list_of_iterables)
for item in chained_iterator:
print(item)
Concepts behind the snippet
itertools.chain()
leverages this by creating a new iterator that sequentially yields elements from each of its input iterators without needing to load all elements into memory at once. This makes it memory-efficient for large datasets.
Real-Life Use Case
Best Practices
chain()
.
Interview Tip
itertools.chain()
works internally. You should be able to contrast iterator chaining with methods that create new collections in memory.
When to use them
Memory footprint
Alternatives
Pros
Cons
FAQ
-
Can I chain an infinite iterator?
Yes, you can chain an infinite iterator with other iterators. However, be careful about the order. If you chain an infinite iterator first, the chain will never reach the subsequent iterators. -
What happens if one of the iterables is empty?
If one of the iterables is empty,itertools.chain()
will simply skip it and move on to the next iterable in the chain. This will not raise an error. -
Is it possible to modify the elements while iterating through a chained iterator?
Modifying the elements while iterating depends on whether the underlying iterables are mutable. If you're iterating over a chained iterator of lists, modifying an element in one of the lists *will* affect the output of the iterator (since the iterator just yields references to the elements of the lists). If the iterables are immutable (like tuples), you cannot modify them.