 <p>You don't say what size numbers you need this to work for, or whether speed is a concern, but here's a very simple unoptimized solution that should work just fine for small inputs (<code>n</code> smaller than <code>10**7</code>, say).</p> <pre><code>def products(n, min_divisor=2): """Generate expressions of n as a product of ints &gt;= min_divisor.""" if n == 1: yield [] for divisor in range(min_divisor, n+1): if n % divisor == 0: for product in products(n // divisor, divisor): yield product + [divisor] </code></pre> <p>To explain the code, think about how you might do this methodically by hand. You could start with the products that contain a <code>2</code>. If <code>n</code> is odd, there aren't any. If <code>n</code> is even, then we can do a simple recursion: find all possible decompositions of <code>n // 2</code>, and then output <code>decomposition * 2</code> for each one. Once we've exhausted all the products containing a <code>2</code>, we move on to products involving a <code>3</code>. But here there's an additional complication: in the first step, we've already found all products involving a <code>2</code>, so to avoid repeated solutions, we want to restrict to products in which <em>every</em> divisor is at least <code>3</code>. So our recursive call needs to keep track of the minimum permitted divisor, <code>min_divisor</code> above. Finally, we need a base case: <code>1</code> is expressible as the empty product.</p> <p>And here's the output for <code>n=24</code>, including the <code>6*2*2</code> case that you missed:</p> <pre><code>&gt;&gt;&gt; for product in products(24): ... print('*'.join(map(str, product))) ... 3*2*2*2 6*2*2 4*3*2 12*2 8*3 6*4 24 </code></pre> <p>This is less than satisfying, though: as other commenters have pointed out, it should be possible to compute the multiplicative partitions of <code>n</code> from the prime factorisation, and even just from the list of exponents in the prime factorisation, using the primes only when it's necessary to reconstruct the factors. Here's a variant of the above that works with an existing prime factorisation. There's still plenty of scope for efficiency improvements: in particular, the <code>itertools.product</code> call and subsequent filtering to ignore everything lexicographically smaller than <code>min_exponents</code> should be replaced with a custom iterator that <em>starts</em> from <code>min_exponents</code>. But this should serve as a starting point.</p> <pre><code>import itertools def exponent_partitions(exponents, min_exponents): """Generate all vector partitions of 'exponents', each of whose entries is lexicographically at least 'min_exponents'.""" if all(exponent == 0 for exponent in exponents): yield [] else: for vector in itertools.product(*(range(v+1) for v in exponents)): if vector &gt;= min_exponents: remainder = tuple(x - y for x, y in zip(exponents, vector)) for partition in exponent_partitions(remainder, vector): yield partition + [vector] def divisor_from_exponents(primes, exponent_vector): """Reconstruct divisor from the list of exponents.""" divisor = 1 for p, e in zip(primes, exponent_vector): divisor *= p**e return divisor def multiplicative_partitions(primes, exponents): """Generate all multiplication partitions of product(p**e for p, e in zip(primes, exponents))""" if len(exponents) == 0: # Corner case for partitions of 1. yield [] else: initial_vector = (0,) * (len(exponents) - 1) + (1,) for partition in exponent_partitions(exponents, initial_vector): yield [divisor_from_exponents(primes, vector) for vector in partition] </code></pre> <p>And the output for <code>24</code>, again: we're writing <code>24</code> as <code>2**3 * 3**1</code>, so the tuple of primes is <code>(2, 3)</code> and the corresponding tuple of exponents is <code>(3, 1)</code>.</p> <pre><code>&gt;&gt;&gt; for product in multiplicative_partitions((2, 3), (3, 1)): ... print('*'.join(map(str, product))) ... 2*2*2*3 4*2*3 8*3 6*2*2 12*2 4*6 24 </code></pre> <p>There's plenty of literature on generating and counting the multiplicative partitions of an integer. See for example the links from <a href="https://oeis.org/A001055" rel="nofollow">OEIS A001055</a>, and the <a href="http://www.sagemath.org/doc/reference/combinat/sage/combinat/vector_partition.html" rel="nofollow">SAGE functions</a> for computing vector partitions.</p>