Overview
Every itertools function returns a lazy iterator: nothing runs until you iterate, and an iterator can be consumed only once. Wrap in list() when you need a sequence. Data-structure helpers are on python-collections.
Chain, repeat, and slice
Use these to avoid building intermediate lists.
| Function | Example | Yields |
|---|---|---|
chain(*its) | chain([1,2],[3]) | 1, 2, 3 |
chain.from_iterable(its) | chain.from_iterable([[1,2],[3]]) | 1, 2, 3 (lazy over the outer iterable) |
zip_longest(*its, fillvalue=None) | zip_longest([1,2],[3]) | (1,3), (2,None) |
count(start, step), cycle(it), repeat(x, n) | count(10, 5) | 10, 15, 20, … (infinite unless repeat has n) |
islice(it, start, stop, step) | islice(range(100), 5, 15, 2) | 5, 7, 9, 11, 13 |
takewhile(pred, it), dropwhile(pred, it) | takewhile(lambda x: x<5, [1,3,6,2]) | 1, 3 |
filterfalse(pred, it), compress(data, sel) | compress("ABCD", [1,0,1,0]) | A, C |
batched(it, n) | batched("abcde", 2) | (‘a’,‘b’), (‘c’,‘d’), (‘e’,) (3.12+; strict= in 3.13) |
pairwise(it) | pairwise("abc") | (‘a’,‘b’), (‘b’,‘c’) (3.10+) |
starmap(fn, it), tee(it, n) | starmap(pow, [(2,3)]) | 8; tee makes independent copies. |
Combinatorics
Check the result count before materializing a combinatoric iterator.
| Function | Example | Count |
|---|---|---|
product(*its, repeat=1) | product([0,1], repeat=2) | n^r; same as nested loops. |
permutations(it, r) | permutations([1,2,3], 2) | n! / (n-r)! |
combinations(it, r) | combinations([1,2,3], 2) | n! / (r! (n-r)!) |
combinations_with_replacement(it, r) | combinations_with_replacement([1,2], 2) | Items may repeat. |
groupby and accumulate
groupby starts a new group whenever the key changes, so sort by the same key first.
from itertools import groupby, accumulate
import operator
rows = sorted(rows, key=lambda r: r["dept"])
by_dept = {k: list(g) for k, g in groupby(rows, key=lambda r: r["dept"])}
list(accumulate([1, 2, 3, 4])) # [1, 3, 6, 10]
list(accumulate([3, 1, 4, 1, 5], max)) # [3, 3, 4, 4, 5]
list(accumulate([1, 2, 3], initial=10)) # [10, 11, 13, 16]
list(accumulate([1, 2, 3, 4], operator.mul)) # [1, 2, 6, 24]Use accumulate for the running series and functools.reduce for only the final value.
Gotchas
Avoid these; each yields empty, repeated, or infinite output.
| Gotcha | Fix |
|---|---|
groupby on unsorted input yields repeated groups for one key. | Sort by the same key first. |
| Each group iterator is invalid once the outer iterator advances. | Consume it with list(g) before moving on. |
cycle, count, and repeat(x) never stop. | Bound them with islice or takewhile. |
product(*[big] * 3) builds n^3 tuples. | Check the count before materializing. |
islice rejects negative indexes. | For the last n items use deque(it, maxlen=n). |
| An exhausted iterator is empty on a second pass. | Use tee, or rebuild the iterator. |