algorithm for python itertools.permutations
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
itertools.permutations generates all possible orderings of elements from an iterable. It returns tuples of a specified length (defaulting to the full length of the input). The function uses a lazy iterator, producing permutations one at a time without generating all of them in memory. Understanding the underlying algorithm helps when you need custom permutation logic or want to optimize for specific use cases.
Basic Usage
The signature is itertools.permutations(iterable, r=None):
iterable: Any iterable (list, tuple, string, range, etc.)r: Length of each permutation tuple. Defaults tolen(iterable)for full-length permutations
How Many Permutations?
The number of r-length permutations from n elements is P(n, r) = n! / (n-r)!:
The Algorithm Behind itertools.permutations
CPython's itertools.permutations uses a variant of the Steinhaus-Johnson-Trotter algorithm adapted for index-based generation. Here is a simplified Python equivalent:
The key idea: maintain an array of indices and a cycles counter. Each step swaps elements and decrements cycle counters. When a cycle reaches zero, it rotates the remaining indices and resets.
Implementing Permutations from Scratch
Recursive Approach
Heap's Algorithm (In-Place)
Heap's algorithm generates permutations by swapping elements in place, minimizing the number of swaps:
Practical Examples
Finding Anagrams
Brute-Force Shortest Path (TSP)
Generating Next Permutation
Performance Considerations
| n | Permutations (n!) | Time |
| 5 | 120 | Instant |
| 8 | 40,320 | Fast |
| 10 | 3,628,800 | ~1 second |
| 12 | 479,001,600 | ~2 minutes |
| 15 | 1,307,674,368,000 | Impractical |
itertools.permutations is a C extension, so it is much faster than pure Python implementations. But factorial growth means anything beyond n=12 becomes impractical for exhaustive enumeration.
Common Pitfalls
- Duplicate elements:
itertools.permutationstreats elements by position, not value.permutations([1, 1, 2])yields(1, 1, 2)twice (once for each1). For unique permutations, wrap inset()or usemore_itertools.distinct_permutations. - Memory:
list(permutations(range(12)))creates 479 million tuples and will exhaust memory. Iterate lazily instead of converting to a list. - Factorial explosion: n! grows extremely fast. For n > 12, consider heuristic or approximate algorithms instead of exhaustive permutation.
- Strings produce tuples:
permutations('abc')yields('a', 'b', 'c')not'abc'. Use''.join(p)to get strings back. - Not sorted input:
itertools.permutationsgenerates permutations in the order of the input indices, not in lexicographic order of values. Sort the input first if you need lexicographic order.
Summary
itertools.permutations(iterable, r)generates r-length orderings lazily using a cycle-based index algorithm- The number of permutations is P(n, r) = n! / (n-r)! — grows factorially
- Use
itertools.permutations(C extension) over pure Python implementations for performance - For unique permutations of duplicates, use
set()ormore_itertools.distinct_permutations - Anything beyond n=12 is impractical for exhaustive enumeration — use heuristics instead

