The itertools module delivers a collection of memory‑efficient, high‑speed iterators inspired by constructs from APL, Haskell, and SML. It standardises a core set of tools that can be used individually or composed to form an "iterator algebra", allowing concise, efficient special‑purpose iterators to be built directly in pure Python. Many of these tools work naturally with the fast functions from the operator module—for example, computing the dot product of two vectors becomes sum(starmap(operator.mul, zip(vec1, vec2, strict=True))).
Infinite Iterators
Three fundamental iterators generate endless sequences:
| Iterator | Arguments | Result | Example |
|---|---|---|---|
count() |
start, [step] | start, start+step, start+2step, … | count(10) → 10 11 12 13 … |
cycle() |
iterabel | p0, p1, … plast, p0, p1, … | cycle('ABCD') → A B C D A B … |
repeat() |
elem [, n] | elem, elem, elem, … (n times) | repeat('Hi', 3) → Hi Hi Hi |
count
count() produces consecutive integers indefinitely. When you need a fixed number of values, combine it with islice or a termination condition.
from itertools import count, islice
# Take the first 5 even numbers starting at 4
stream = count(4, step=2)
limited = islice(stream, 5)
print(list(limited)) # [4, 6, 8, 10, 12]
oregulate repetitive tasks with count() and zip:
from itertools import count
items = ['apple', 'banana', 'cherry']
for idx, fruit in zip(count(1), items):
print(f"{idx}: {fruit}")
cycle
cycle() loops over an iterable forever. Use islice to sample a fixed number of repetitions.
from itertools import cycle, islice
colors = ['red', 'green', 'blue']
cycled = cycle(colors)
batch = list(islice(cycled, 8))
print(batch) # ['red', 'green', 'blue', 'red', 'green', 'blue', 'red', 'green']
Licence patterns can be simulated by cycling a small set of characters:
from itertools import cycle
pattern = cycle('XO')
for _ in range(6):
print(next(pattern), end=' ')
# Output: X O X O X O
repeat
repeat() emits the same value over and over, either infiniteyl or a specified number of times.
from itertools import repeat
# Repeat a constant three times
for value in repeat(42, 3):
print(value)
# Output:
# 42
# 42
# 42
prepare placeholder data structures quickly:
initial_counts = list(repeat(0, 5))
print(initial_counts) # [0, 0, 0, 0, 0]
Iterators Terminating on the Shortest Input
This large family yields values until one of the input iterables is exhausted. Important members include accumulate, chain, compress, dropwhile, takewhile, zip_longest, and many more.
accumulate
accumulate() successively applies a binary function, defaulting to addition. It emits each intermediate result.
from itertools import accumulate
import operator
values = [5, 3, 6, 2]
cumulative_sum = list(accumulate(values))
cumulative_product = list(accumulate(values, operator.mul))
print(cumulative_sum) # [5, 8, 14, 16]
print(cumulative_product) # [5, 15, 90, 180]
lieration of strings is also possible:
from itertools import accumulate
letters = 'PYTHON'
for step in accumulate(letters):
print(step)
# Output:
# P
# PY
# PYT
# PYTH
# PYTHO
# PYTHON
chain and chain.from_iterable
chain() concatenates multiple iterables into a single sequence, while chain.from_iterable() flattens an iterable of iterables.
from itertools import chain
numbers = [1, 2, 3]
letters = ['a', 'b']
combined = list(chain(numbers, letters))
print(combined) # [1, 2, 3, 'a', 'b']
from itertools import chain
list_of_lists = [[10, 20], [30, 40], [50]]
flat = list(chain.from_iterable(list_of_lists))
print(flat) # [10, 20, 30, 40, 50]
compress
compress() filters elements from the data iterable based on a corresponding selector iterable of Boolean‑like values.
from itertools import compress
names = ['Alice', 'Bob', 'Charlie', 'Diana']
flags = [True, False, True, True]
selected = list(compress(names, flags))
print(selected) # ['Alice', 'Charlie', 'Diana']
dropwhile and takewhile
These condition‑driven iterators consume elements while (or until) a predicate stops holding.
from itertools import dropwhile, takewhile
scores = [2, 4, 6, 1, 8, 3]
after_first_high = list(dropwhile(lambda x: x < 5, scores))
until_low = list(takewhile(lambda x: x % 2 == 0, scores))
print(after_first_high) # [6, 1, 8, 3]
print(until_low) # [2, 4]
zip_longest
While the standard zip stops at the shortest input, zip_longest continues until all iterables are exhausted, filling missing values with a specified constant.
from itertools import zip_longest
days = ['Mon', 'Tue']
activities = ['gym', 'swim', 'run']
paired = list(zip_longest(days, activities, fillvalue='rest'))
print(paired) # [('Mon', 'gym'), ('Tue', 'swim'), ('rest', 'run')]
Many other powerful tools—batched, filterfalse, groupby, islice, pairwise, starmap, tee—extend this toolkit. Combined withawn imagination they enable elegant, declarative data processing pipelines that are both readable and memory‑friendly.