Python itertools: Permutations vs Combinations
Python's itertools module provides specialized functions
for combinatorial computing, most notably permutations()
and combinations(). While both functions take an input
collection and generate subsets of a specified length, the key
distinction lies in whether the order of elements matters.
permutations() treats different orderings of the same items
as unique outcomes, whereas combinations() considers order
irrelevant, returning only unique groupings regardless of sequence.
The Core Difference: Order Matters vs. Order Does Not Matter
The fundamental distinction between these two functions comes down to mathematics:
permutations()(Order matters): The arrangement('A', 'B')is treated as distinct from('B', 'A').combinations()(Order does not matter): The arrangement('A', 'B')and('B', 'A')are considered identical, so only one instance is produced.
Neither function allows an element at a specific index to be repeated with itself unless the input iterable contains duplicate values.
How
itertools.permutations() Works
itertools.permutations(iterable, r=None) returns
successive \(r\)-length permutations of
elements from the provided iterable.
- The parameter
rdefines the length of each output tuple. - If
ris not specified or isNone,rdefaults to the length of the iterable, generating full-length permutations.
import itertools
data = ['A', 'B', 'C']
# Generate 2-element permutations
result = list(itertools.permutations(data, 2))
print(result)Output:
[('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]Notice that both ('A', 'B') and ('B', 'A')
are present in the output.
How
itertools.combinations() Works
itertools.combinations(iterable, r) returns \(r\)-length subsequences of elements from
the input iterable.
- The parameter
ris mandatory; omitting it raises aTypeError. - Elements are returned in lexicographic order based on the input order. If the input iterable is sorted, the combination tuples will also be produced in sorted order.
import itertools
data = ['A', 'B', 'C']
# Generate 2-element combinations
result = list(itertools.combinations(data, 2))
print(result)Output:
[('A', 'B'), ('A', 'C'), ('B', 'C')]Because order does not matter, ('B', 'A') is omitted
because its items are already represented by
('A', 'B').
Direct Comparison
| Feature | itertools.permutations() |
itertools.combinations() |
|---|---|---|
| Order Significance | Order matters | Order does not matter |
| Duplicate Sets | Yields both (x, y) and
(y, x) |
Yields only (x, y) |
Length Argument
(r) |
Optional (defaults to length of input) | Required |
| Result Count Formula | \(P(n, r) = \frac{n!}{(n-r)!}\) | \(C(n, r) = \frac{n!}{r!(n-r)!}\) |
| Size of Output | Always greater than or equal to combinations | Always smaller than or equal to permutations |
When to Use Which
- Use
permutations()when sequencing is critical to the problem. Examples include calculating seating arrangements, route scheduling (like the Traveling Salesperson Problem), or solving password and anagram puzzles. - Use
combinations()when grouping items where the sequence does not change the result. Examples include selecting a committee from a pool of candidates, dealing a hand of cards, or creating lottery number sets.