combinatorics
permutations
algorithms
programming
number combinations

Getting all possible combinations from a list of numbers

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

When people ask for "all possible combinations" of a list, they often mean one of several different things: combinations of a fixed size, all subsets of every size, or permutations where order matters. The first step is to decide which of those results you actually need.

Once that is clear, the implementation is straightforward. In Python, the itertools module already provides efficient generators for the most common variants, so you rarely need to write the combinatorics logic yourself.

Combinations of a Fixed Length

If order does not matter and each element can be used at most once, use itertools.combinations.

python
1from itertools import combinations
2
3numbers = [1, 2, 3, 4]
4
5result = list(combinations(numbers, 2))
6print(result)

Output:

python
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]

This returns all unique 2-element combinations. Notice that (1, 2) appears, but (2, 1) does not, because combinations ignore ordering.

Generate All Combination Sizes

If you want every possible non-empty subset, iterate over all valid lengths:

python
1from itertools import combinations
2
3numbers = [1, 2, 3]
4all_combinations = []
5
6for r in range(1, len(numbers) + 1):
7    all_combinations.extend(combinations(numbers, r))
8
9print(all_combinations)

Output:

python
[(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]

That pattern effectively gives you the power set minus the empty set.

Include the Empty Combination if Needed

In some algorithms, the empty subset is meaningful. If so, start the range at 0:

python
1from itertools import combinations
2
3numbers = [1, 2, 3]
4power_set = [
5    combo
6    for r in range(0, len(numbers) + 1)
7    for combo in combinations(numbers, r)
8]
9
10print(power_set)

The first item will be (), which represents the empty combination.

Use Permutations When Order Matters

If (1, 2) and (2, 1) should count as different results, you want permutations instead:

python
1from itertools import permutations
2
3numbers = [1, 2, 3]
4result = list(permutations(numbers, 2))
5print(result)

Output:

python
[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]

That distinction is essential. Many bugs come from choosing combinations when the algorithm actually depends on sequence order.

Write It Yourself with Recursion

If you need to understand the mechanics, a recursive solution is educational:

python
1def combinations_of_size(values, size):
2    result = []
3
4    def backtrack(start, path):
5        if len(path) == size:
6            result.append(tuple(path))
7            return
8
9        for index in range(start, len(values)):
10            path.append(values[index])
11            backtrack(index + 1, path)
12            path.pop()
13
14    backtrack(0, [])
15    return result
16
17
18print(combinations_of_size([1, 2, 3, 4], 3))

This generates the same result as itertools.combinations, but the standard library version is faster and more memory-efficient because it is implemented in optimized native code.

Watch Out for Combinatorial Explosion

The number of results grows quickly. Even for moderate input sizes, generating every combination can become expensive in both time and memory.

For example, 20 items already produce over one million subsets if you want the full power set. That means you should prefer generators and stream the results when possible:

python
1from itertools import combinations
2
3for combo in combinations(range(100), 3):
4    process(combo)

This avoids building a massive list in memory all at once.

Common Pitfalls

  • Saying "combinations" when the real requirement is permutations.
  • Converting everything to a list too early and exhausting memory on large inputs.
  • Forgetting whether the empty set should be included.
  • Ignoring duplicate values in the input list. Position-based combinations may still produce repeated tuples if the source values repeat.
  • Reimplementing combinatorics manually when itertools already solves the problem cleanly.

Summary

  • Use itertools.combinations when order does not matter.
  • Loop over different lengths if you need every subset size.
  • Use itertools.permutations when order matters.
  • Prefer generator-based iteration for large result sets.
  • Clarify the exact meaning of "all possible combinations" before coding.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.