itertools.product() / itertools.permutations() / itertools.combinations()
| Since: | Python 2(2000) |
|---|
itertools.product() generates the Cartesian product of multiple iterables. The Cartesian product refers to all possible combinations of choosing one element from each group. For example, 3 colors × 3 sizes gives 9 combinations. itertools.permutations() generates permutations (ordered, no repetition), and itertools.combinations() generates combinations (unordered, no repetition). These functions use lazy evaluation and do not hold results in memory, so they can handle a large number of combinations efficiently.
Syntax
import itertools # Cartesian product itertools.product(*iterables, repeat=1) # Permutations (no repetition) itertools.permutations(iterable, r=None) # Combinations (no repetition) itertools.combinations(iterable, r) # Combinations (with repetition) itertools.combinations_with_replacement(iterable, r)
Function List
| Function | Description |
|---|---|
| product(*iterables, repeat=1) | Generates the Cartesian product of multiple iterables as tuples. Use repeat to repeat the same iterable multiple times. |
| permutations(iterable, r) | Generates all permutations of r elements. If r is omitted, permutations of all elements are generated. |
| combinations(iterable, r) | Generates all combinations of r elements (no repetition). |
| combinations_with_replacement(iterable, r) | Generates all combinations of r elements (with repetition allowed). |
Sample Code
itertools_product.py
import itertools # product: Cartesian product (all combinations) grades = ['Special Grade', 'Grade 1', 'Grade 2'] sorcerers = ['Gojo Satoru', 'Itadori Yuji'] result = list(itertools.product(grades, sorcerers)) print(result) # product: Cartesian product of the same list using repeat (two dice) dice = list(itertools.product(range(1, 7), repeat=2)) print(len(dice)) print(dice[:3])
Running the code produces the following output:
python3 itertools_product.py
[('Special Grade', 'Gojo Satoru'), ('Special Grade', 'Itadori Yuji'), ('Grade 1', 'Gojo Satoru'), ('Grade 1', 'Itadori Yuji'), ('Grade 2', 'Gojo Satoru'), ('Grade 2', 'Itadori Yuji')]
36
[(1, 1), (1, 2), (1, 3)]
itertools_permutations.py
import itertools # permutations: permutations (ordered, no repetition) sorcerers = ['Fushiguro Megumi', 'Kugisaki Nobara', 'Nanami Kento'] perms = list(itertools.permutations(sorcerers, 2)) print(perms) # permutations: permutations of all elements all_perms = list(itertools.permutations([1, 2, 3])) print(len(all_perms))
Running the code produces the following output:
python3 itertools_permutations.py
[('Fushiguro Megumi', 'Kugisaki Nobara'), ('Fushiguro Megumi', 'Nanami Kento'), ('Kugisaki Nobara', 'Fushiguro Megumi'), ('Kugisaki Nobara', 'Nanami Kento'), ('Nanami Kento', 'Fushiguro Megumi'), ('Nanami Kento', 'Kugisaki Nobara')]
6
itertools_combinations.py
import itertools # combinations: combinations (unordered, no repetition) combs = list(itertools.combinations([1, 2, 3, 4], 2)) print(combs) # combinations_with_replacement: combinations with repetition allowed combs_rep = list(itertools.combinations_with_replacement(['A', 'B', 'C'], 2)) print(combs_rep)
Running the code produces the following output:
python3 itertools_combinations.py
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]
Common Mistakes
Common Mistake 1: Underestimating the number of results from product()
The Cartesian product grows multiplicatively with the size of the inputs. The number of results can explode rapidly, so it is a good habit to check the count before materializing everything into a list.
import itertools # NG: converting a huge Cartesian product directly to a list # range(100) repeated 5 times = 100^5 = 10,000,000,000 combinations result = list(itertools.product(range(100), repeat=5)) print(len(result))
mistake1_ok.py
import itertools
grades = ['Special Grade', 'Grade 1', 'Grade 2']
sorcerers = ['Gojo Satoru', 'Itadori Yuji', 'Fushiguro Megumi']
# OK: check the count first, then decide whether to proceed
count = sum(1 for _ in itertools.product(grades, sorcerers))
print(f"Total combinations: {count}")
if count <= 1000:
result = list(itertools.product(grades, sorcerers))
print(result[:3])
Running the code produces the following output:
python3 mistake1_ok.py
Total combinations: 9
[('Special Grade', 'Gojo Satoru'), ('Special Grade', 'Itadori Yuji'), ('Special Grade', 'Fushiguro Megumi')]
Common Mistake 2: Confusing permutations and combinations
permutations is ordered (AB and BA are different), while combinations is unordered (AB and BA are the same). Choose based on whether the order of elements matters.
mistake2_ng.py
import itertools
# NG: using permutations to find team pairs — produces duplicates with different order
team_members = ['Gojo Satoru', 'Itadori Yuji', 'Fushiguro Megumi', 'Kugisaki Nobara']
pairs = list(itertools.permutations(team_members, 2))
print(f"count: {len(pairs)}")
print(pairs[:4])
Running the code produces the following output:
python3 mistake2_ng.py
count: 12
[('Gojo Satoru', 'Itadori Yuji'), ('Gojo Satoru', 'Fushiguro Megumi'), ('Gojo Satoru', 'Kugisaki Nobara'), ('Itadori Yuji', 'Gojo Satoru')]
For team pairs, (Gojo, Itadori) and (Itadori, Gojo) represent the same pair. Use combinations to get each unique pair only once.
mistake2_ok.py
import itertools
# OK: use combinations for team pairs
team_members = ['Gojo Satoru', 'Itadori Yuji', 'Fushiguro Megumi', 'Kugisaki Nobara']
pairs = list(itertools.combinations(team_members, 2))
print(f"count: {len(pairs)}")
print(pairs)
Running the code produces the following output:
python3 mistake2_ok.py
count: 6
[('Gojo Satoru', 'Itadori Yuji'), ('Gojo Satoru', 'Fushiguro Megumi'), ('Gojo Satoru', 'Kugisaki Nobara'), ('Itadori Yuji', 'Fushiguro Megumi'), ('Itadori Yuji', 'Kugisaki Nobara'), ('Fushiguro Megumi', 'Kugisaki Nobara')]
Notes
All of these functions return an iterator of tuples. Be aware that as the number of elements grows, the number of generated combinations increases exponentially. For example, the number of permutations choosing r from n elements is P(n,r) = n!/(n-r)!, and the number of combinations is C(n,r) = n!/(r!(n-r)!).
The repeat option of product() lets you efficiently generate the Cartesian product of the same iterable used multiple times. You can achieve the same result with nested for loops, but using product results in more concise code. These functions are useful for brute-force searches and automatic test case generation.
If you find any errors or copyright issues, please contact us.