Back to Blog
Python

Python Combinations vs Permutations: How to Choose

python combinations vs permutations: Understand the difference between Python combinations and permutations, when to use each, and how to avoid common pitfalls.

itertoolscombinationspermutationsalgorithm designcombinatorics
Two groups of colored balls: one group with ordered sequences and another with unordered selections, illustrating combinations vs permutations.

When you need to generate all possible selections from a collection in Python, the standard library's itertools module provides two closely related tools: combinations and permutations. The difference between python combinations vs permutations comes down to whether order matters. A permutation treats (A, B) and (B, A) as distinct, while a combination treats them as the same selection. That single distinction drives every other difference in syntax, output size, and use case.

What itertools.combinations Produces

The combinations(iterable, r) function yields tuples of length r in lexicographic order, without repeated elements. Each tuple is an unordered selection, meaning the order of elements inside the tuple is not considered significant. The tuples themselves are emitted in a deterministic order based on the input sequence, but (A, B) and (B, A) never both appear.

from itertools import combinations print(list(combinations(['A', 'B', 'C'], 2))) # [('A', 'B'), ('A', 'C'), ('B', 'C')]

The output contains every way to pick two items from three, ignoring order. This is exactly the mathematical definition of a combination.

What itertools.permutations Produces

The permutations(iterable, r=None) function yields all possible orderings of r elements from the input. If r is omitted, it defaults to len(iterable), producing all full-length permutations. Each tuple is an ordered arrangement, so (A, B) and (B, A) are distinct results.

from itertools import permutations print(list(permutations(['A', 'B', 'C'], 2))) # [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]

Notice that the same two elements appear in both orders. This is the key difference from combinations.

Key Differences: Order, Repetition, and Output Size

The most important distinction is order sensitivity. Combinations ignore internal order; permutations do not. Both functions assume the input elements are unique by position, so they do not repeat an element within a single tuple. If you need repetition, you must use combinations_with_replacement or product with repeat.

Propertycombinationspermutations
Order mattersNoYes
Repetition allowedNoNo
Output count for n items, r selectednCr = n! / (r!(n-r)!)nPr = n! / (n-r)!
Typical useSubsets, teams, lottery picksRankings, sequences, arrangements

The count difference is dramatic. For n=10 and r=4, there are 210 combinations but 5040 permutations. As n and r grow, permutations explode much faster.

Choosing the Right Function for Your Problem

Your choice depends entirely on whether the order of the selected items changes the outcome. If you are selecting a committee from a list of people, the order of selection does not matter, so use combinations. If you are generating possible passwords from a set of characters, the order matters, so use permutations.

Consider a scenario where you need to assign three distinct roles (president, treasurer, secretary) from five candidates. Since each role is different, permutations(candidates, 3) is correct. If you only need to choose three people to form a team, combinations(candidates, 3) is the right tool.

A common mistake is using permutations when the problem is actually about subsets. Ask yourself: would swapping two selected items produce a different valid result? If not, you need combinations.

Performance and Memory Considerations

Both functions return lazy iterators, so they generate tuples one at a time. This is memory-efficient for iteration, but the total number of results can become impractical. The output size grows factorially for permutations and polynomially for combinations. For even moderate input sizes, materializing the full result into a list can exhaust memory.

from itertools import permutations # n=10, r=10 -> 3,628,800 tuples for perm in permutations(range(10)): # process each permutation pass

This loop will run 3.6 million times, which is fine if the body is cheap, but you should avoid storing all results unless you know the count is manageable. The memory per tuple is proportional to r, but the number of tuples dominates. Prefer streaming processing over list() when the count is large.

Common Mistakes and Edge Cases

Several edge cases trip up developers new to these functions.

  • r greater than n: Both functions return an empty iterator. This is often unexpected but correct.
  • r equal to zero: Both return a single empty tuple. This matches the mathematical convention that there is exactly one way to choose nothing.
  • Duplicate elements in the input: itertools treats each element by its position, not its value. If your input contains duplicate values, the output will contain duplicate tuples. Use set() on the input or on the output to deduplicate, but be aware that this changes the count and may be expensive.
  • Forgetting that permutations with r omitted uses len(iterable): This produces n! results, which can be enormous even for small n. Always specify r unless you truly need all full-length permutations.

Related Tools: combinations_with_replacement and product

When repetition is allowed, the standard combinations and permutations are insufficient. combinations_with_replacement(iterable, r) allows the same element to appear multiple times in a tuple, but still ignores order. For example, selecting two scoops of ice cream from five flavors where you can pick the same flavor twice is a combination with replacement.

from itertools import combinations_with_replacement print(list(combinations_with_replacement(['A', 'B', 'C'], 2))) # [('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]

For ordered selections with repetition, use product(iterable, repeat=r). This produces the Cartesian product, which is the same as permutations with replacement.

from itertools import product print(list(product(['A', 'B'], repeat=2))) # [('A', 'A'), ('A', 'B'), ('B', 'A'), ('B', 'B')]

Understanding these four functions gives you complete coverage of ordered and unordered selections with and without repetition.

A Practical Decision Rule

When you face a selection problem, apply this rule in order. First, determine whether repetition is allowed. If yes, use combinations_with_replacement for unordered selections or product for ordered ones. If no, check whether order matters. If order matters, use permutations; if not, use combinations. This simple branching logic covers the vast majority of combinatorics problems in Python. For example, generating all possible 4-digit PINs from digits 0-9 is product(range(10), repeat=4) because order matters and repetition is allowed. Selecting a hand of 5 cards from a deck is combinations(deck, 5) because order does not matter and repetition is impossible. Keeping this decision tree in mind prevents the most common misuse of these powerful iterators.

python combinations vs permutations: Practical Usage and Cod | RYUSLOG DEV