Python itertools Cheat Sheet
This page contains a condensed overview of Python’s itertools module. It covers infinite iterators, slicing and chaining, chunking with batched() and pairwise(), combinatorics, accumulating and filtering, and grouping with groupby(). You can also download the information as a printable cheat sheet:
Free Bonus: Python itertools Cheat Sheet
Get a Python itertools Cheat Sheet (PDF) with infinite iterators, chunking, combinatorics, accumulating, and grouping on one printable page:
Practice with hands-on coding exercises, quizzes, and a personal AI mentor. Not sure what to learn next? Get your free personal learning plan.
New to itertools?
Iterator Basics
- Every
itertoolsfunction returns a lazy iterator - Wrap a result in
list()to see its values - Iterators are single-use: once consumed, they’re empty
zip(),map(), andfilter()are lazy too
Import the Module
import itertools as it
Compose Iterators
>>> list(map(sum, zip([1, 2], [3, 4])))
[4, 6]
Iterators Get Exhausted
nums = iter([1, 2, 3])
list(nums) # [1, 2, 3]
list(nums) # []
Want to go deeper on iterators?
Infinite Iterators
- Stop them with
islice(),zip(), ortakewhile() repeat(x, n)stops afternitems
count()
it.count() # 0, 1, 2, 3, ...
it.count(1, step=2) # 1, 3, 5, 7, ...
it.count(0.5, 0.75) # 0.5, 1.25, 2.0, ...
repeat() and cycle()
it.repeat(1) # 1, 1, 1, ...
it.repeat(4, 3) # 4, 4, 4
it.cycle([1, -1]) # 1, -1, 1, -1, ...
Number Items Without a Loop
list(zip(it.count(), "abc"))
# [(0, 'a'), (1, 'b'), (2, 'c')]
What if an infinite iterator never stops?
Slice, Chain, and Copy
islice()works like[start:stop:step], minus negative indicestee()buffers values; if one copy runs far ahead, use alist
islice()
it.islice("ABCDEFG", 2, 5) # C D E
it.islice("ABCDE", 4) # A B C D
it.islice(range(10), 0, 10, 3) # 0 3 6 9
it.islice(it.count(), 3, None) # 3 4 ...
chain() and chain.from_iterable()
it.chain("ABC", "DE") # A B C D E
nested = [[1, 2], [3, 4]]
it.chain.from_iterable(nested) # 1 2 3 4
Flatten Into a List (3.15+)
[*row for row in nested] # [1, 2, 3, 4]
tee()
a, b = it.tee([1, 2, 3])
list(a) # [1, 2, 3]
list(b) # [1, 2, 3]
Cut a Deck of Cards Lazily
def cut(deck, n):
d1, d2 = it.tee(deck)
top = it.islice(d1, n)
bottom = it.islice(d2, n, None)
return it.chain(bottom, top)
Is tee() really free?
Chunks and Pairs
batched()(3.12+) replaces the oldgrouper()recipestrict=True(3.13+) rejects a short final batchpairwise()(3.10+) works on any iterable, not just sequences
batched()
nums = range(1, 11)
list(it.batched(nums, 4))
# [(1, 2, 3, 4), (5, 6, 7, 8), (9, 10)]
list(it.batched(nums, 4, strict=True))
# ValueError: batched(): incomplete batch
zip_longest()
list(it.zip_longest([1, 2, 3], "ab"))
# [(1, 'a'), (2, 'b'), (3, None)]
list(it.zip_longest("ab", [1], fillvalue=0))
# [('a', 1), ('b', 0)]
pairwise()
list(it.pairwise("ABCD"))
# [('A', 'B'), ('B', 'C'), ('C', 'D')]
prices = [100, 104, 99, 105]
[b - a for a, b in it.pairwise(prices)]
# [4, -5, 6]
Think you can chunk and pair without looking?
Free Bonus: Download the Python itertools Cheat Sheet PDF and keep the essentials at hand.
Combinatorics
product()replaces nestedforloops- Items count by position, not value, so duplicates repeat
- Results explode: 10 items have 3,628,800 orderings
product()
list(it.product([1, 2], "ab"))
# [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
len(list(it.product("01", repeat=3))) # 8
combinations()
list(it.combinations([1, 2, 3], 2))
# [(1, 2), (1, 3), (2, 3)]
list(it.combinations_with_replacement(
[1, 2], 2))
# [(1, 1), (1, 2), (2, 2)]
permutations()
list(it.permutations("abc", 2))
# [('a', 'b'), ('a', 'c'), ('b', 'a'),
# ('b', 'c'), ('c', 'a'), ('c', 'b')]
Brute-Force Change for $100
bills = [20, 20, 20, 10, 10, 10, 10, 10,
5, 5, 1, 1, 1, 1, 1]
ways = {c for n in range(1, len(bills) + 1)
for c in it.combinations(bills, n)
if sum(c) == 100}
len(ways) # 5
Mixing up the combinatoric functions?
Accumulate and Filter
accumulate()callsfunc(running, item)initial=adds a starting value to the outputtakewhile()stops at the first false item;dropwhile()starts there
accumulate()
it.accumulate([1, 2, 3, 4]) # 1 3 6 10
it.accumulate([9, 5, 7, 2], min) # 9 5 5 2
it.accumulate([1, 2], initial=100)
# 100 101 103
Fibonacci With accumulate()
fibs = map(lambda p: p[0], it.accumulate(
it.repeat(None),
lambda p, _: (p[1], p[0] + p[1]),
initial=(0, 1),
))
list(it.islice(fibs, 8))
# [0, 1, 1, 2, 3, 5, 8, 13]
filterfalse()
nums = [0, 1, -1, 2, -2]
it.filterfalse(lambda x: x <= 0, nums)
# 1 2
takewhile() and dropwhile()
nums = [0, 1, 2, 3, 4, 1]
it.takewhile(lambda x: x < 3, nums) # 0 1 2
it.dropwhile(lambda x: x < 3, nums) # 3 4 1
starmap() and compress()
it.starmap(pow, [(2, 3), (3, 2)]) # 8 9
it.compress("ABCD", [1, 0, 1, 1]) # A C D
Want more practice with functional tools?
Grouping With groupby()
groupby()only groups neighboring items with equal keys- Sort by the same key first to get one group per key
- Each group is an iterator; use it before advancing
Group Neighbors
for k, g in it.groupby("AAABBA"):
print(k, list(g))
# A ['A', 'A', 'A']
# B ['B', 'B']
# A ['A']
Sort, Then Group
words = ["hi", "cat", "yo", "dog", "a"]
words.sort(key=len)
for size, grp in it.groupby(words, key=len):
print(size, list(grp))
# 1 ['a']
# 2 ['hi', 'yo']
# 3 ['cat', 'dog']
Pick Relay Teams of Four
times = {"Ana": 52, "Bo": 49, "Cy": 55,
"Di": 50, "Ed": 51, "Fy": 53}
fastest = sorted(times, key=times.get)
dict(zip("AB", it.batched(fastest, 4)))
# {'A': ('Bo', 'Di', 'Ed', 'Ana'),
# 'B': ('Fy', 'Cy')}
Dive deeper with the full tutorial:
Ready to test yourself on groupby()?
Ready to go beyond the cheat sheet?
You can download this information as a printable cheat sheet:
Free Bonus: Python itertools Cheat Sheet
Get a Python itertools Cheat Sheet (PDF) with infinite iterators, chunking, combinatorics, accumulating, and grouping on one printable page: