Programming
Algorithms
Data Structures
List Permutations
Coding Tips

How do I generate all permutations of a list?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Generating all permutations of a list means producing every possible ordering of its elements. It is a classic combinatorics problem, but in programming the practical question is usually not only how to generate them, but also whether generating all of them is affordable at all.

The Simple Answer in Python

If you are using Python, the easiest and most reliable solution is itertools.permutations.

python
1from itertools import permutations
2
3items = [1, 2, 3]
4
5for perm in permutations(items):
6    print(perm)

This yields:

  • '(1, 2, 3)'
  • '(1, 3, 2)'
  • '(2, 1, 3)'
  • '(2, 3, 1)'
  • '(3, 1, 2)'
  • '(3, 2, 1)'

The function returns an iterator, which is important. It means you can loop over permutations lazily instead of building a huge list in memory immediately.

Why the Number Explodes So Quickly

For a list of length n, the number of permutations is n!, pronounced "n factorial." That growth gets large very fast:

  • 3 items gives 6 permutations
  • 5 items gives 120 permutations
  • 10 items gives 3,628,800 permutations

This is why permutation code often looks fine in examples and then becomes unusable on real input sizes. The algorithm may be correct, but the problem size may simply be too large.

A Recursive Implementation

If you want to understand the mechanics instead of relying on itertools, a recursive generator is a good teaching example.

python
1def permute(items):
2    if len(items) <= 1:
3        yield items
4        return
5
6    for index, item in enumerate(items):
7        remaining = items[:index] + items[index + 1 :]
8        for tail in permute(remaining):
9            yield [item] + tail
10
11
12for perm in permute([1, 2, 3]):
13    print(perm)

The idea is straightforward:

  • choose one item for the front
  • recursively permute the rest
  • prepend the chosen item to each smaller permutation

This is elegant and easy to reason about, though it is usually slower than the built-in iterator for production work.

When You Need a List Instead of an Iterator

Sometimes an API expects all permutations in memory at once. In that case, you can materialize them explicitly.

python
1from itertools import permutations
2
3all_perms = list(permutations(["a", "b", "c"]))
4print(all_perms)

This is fine for tiny inputs, but it becomes expensive fast. If you only need to inspect or test each permutation one at a time, keep the iterator form instead.

Handling Duplicates

If the input list contains repeated values, naive permutation generation will include repeated outputs.

python
1from itertools import permutations
2
3items = [1, 1, 2]
4unique_perms = set(permutations(items))
5print(unique_perms)

Using a set can remove duplicates for small inputs, but it also forces all results into memory. For larger problems, it is often better to generate unique permutations directly with a specialized approach rather than generate everything and deduplicate afterwards.

Common Pitfalls

The biggest mistake is ignoring factorial growth. An algorithm that is perfectly fine for four elements can become unusable for ten or eleven.

Another mistake is converting the iterator to a list too early. If you write list(permutations(items)) out of habit, you lose the memory advantage of lazy generation.

Be careful with duplicate inputs. If the list contains repeated elements, a naive generator treats positions as distinct and can emit repeated arrangements.

Finally, do not generate all permutations if the real task only needs the first match or the best match. In many problems, pruning or backtracking with early exit is much better than full enumeration.

Summary

  • In Python, itertools.permutations is the standard way to generate permutations.
  • The result is an iterator, which helps avoid unnecessary memory usage.
  • A recursive generator is useful for understanding how permutation generation works.
  • The number of permutations grows as n!, so size becomes a problem quickly.
  • Watch for duplicate inputs and avoid materializing all results unless you truly need them.

Course illustration
Course illustration

All Rights Reserved.