Python
Programming
Prime Factors
List Comprehension
Algorithms

I have a Python list of the prime factors of a number. How do I pythonically find all the factors?

Master System Design with Codemia

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

Introduction

If you already have the prime factors of a number, finding all of its factors becomes a combinatorics problem rather than a factoring problem. The cleanest Python approach is to group equal prime factors by exponent and then generate every valid product from those exponent ranges.

Why Prime Factors Are Enough

Suppose the prime factors are [2, 2, 3]. That means the number is:

2^2 * 3^1

Every factor is formed by choosing an exponent for each prime between 0 and its maximum exponent:

  • for 2, choose 0, 1, or 2
  • for 3, choose 0 or 1

Multiplying all valid choices produces every factor exactly once.

Group the Prime Factors First

Use Counter to turn a flat list into prime-exponent counts.

python
1from collections import Counter
2
3prime_factors = [2, 2, 3]
4counts = Counter(prime_factors)
5print(counts)

That produces a mapping like Counter({2: 2, 3: 1}), which is much easier to work with than repeated raw values.

Generate All Factors

Use itertools.product to iterate over every exponent combination, then multiply the selected prime powers.

python
1from collections import Counter
2from itertools import product
3from math import prod
4
5
6def all_factors_from_primes(prime_factors: list[int]) -> list[int]:
7    counts = Counter(prime_factors)
8    primes = sorted(counts.items())
9
10    exponent_ranges = [range(exponent + 1) for _, exponent in primes]
11
12    factors = []
13    for exponents in product(*exponent_ranges):
14        factor = prod(prime ** exponent for (prime, _), exponent in zip(primes, exponents))
15        factors.append(factor)
16
17    return sorted(factors)
18
19
20print(all_factors_from_primes([2, 2, 7]))
21print(all_factors_from_primes([2, 2, 3, 5]))

This is both Pythonic and mathematically correct. It avoids duplicate factors naturally because each exponent combination is unique.

A Simpler Incremental Alternative

For smaller inputs, another nice pattern is to build factors incrementally by multiplying existing results with each prime factor.

python
1def factors_incremental(prime_factors: list[int]) -> list[int]:
2    factors = {1}
3    for prime in prime_factors:
4        factors |= {factor * prime for factor in factors}
5    return sorted(factors)
6
7
8print(factors_incremental([2, 2, 7]))

This works well and is concise, but the exponent-based version makes the math more explicit and scales more predictably in reasoning.

Why Combinations Alone Are Not Ideal

People often reach for itertools.combinations, but combinations on the raw list can be awkward because duplicate primes create repeated products and require deduplication logic anyway.

For example, with [2, 2, 7], choosing the first 2 or the second 2 produces the same factor. The exponent-based method avoids that redundancy by construction.

Factor Count and Output Size

The number of factors is determined by the exponents. If the prime factorization is:

p1^a * p2^b * p3^c

then the number of factors is:

(a + 1) * (b + 1) * (c + 1)

That means generating all factors is inherently proportional to the number of factors you ask for. There is no algorithmic trick that avoids producing them if you need the full list.

A Complete Example with Verification

This example rebuilds the original number and confirms every generated factor divides it evenly.

python
1from math import prod
2
3primes = [2, 2, 3, 5]
4number = prod(primes)
5factors = all_factors_from_primes(primes)
6
7print("number:", number)
8print("factors:", factors)
9print("all valid:", all(number % factor == 0 for factor in factors))

That is a useful sanity check when you first implement the function.

Choosing the Better Style

Use the exponent-based approach when:

  • you want mathematically clean logic
  • you want unique factors without post-processing
  • you care about making the relationship to factorization obvious

Use the incremental set-building approach when:

  • inputs are small
  • you want short code
  • you do not mind using a set to deduplicate naturally

Both are legitimate. The first is usually the better teaching and maintenance choice.

Common Pitfalls

The most common mistake is using combinations of the raw prime-factor list and then wondering why duplicates appear. Another is forgetting to include 1, which is always a factor. Teams also sometimes generate factors but forget to sort them, which makes debugging and testing harder. Finally, if the input list contains values that are not actually prime factors, the algorithm still produces products, but the mathematical interpretation is no longer what you think it is.

Summary

  • Once you know the prime factors, all factors come from exponent combinations.
  • 'Counter plus itertools.product is a clean Pythonic solution.'
  • The exponent-based method avoids duplicate factors naturally.
  • A set-based incremental multiplication approach also works for small inputs.
  • Include 1, sort the output, and validate assumptions about the input list.

Course illustration
Course illustration

All Rights Reserved.