Given positive integers a,b,c and limit, I want to generate all products having the form
$$p^aq^br^c \leq limit$$ less than limit (where p,q,r are distinct primes). a,b and c are not necessary distinct.

I tried something like:

primes= [ 2,3,5,...] # primes up to 10**8
[ (p**a)*(q**b)*(r**c) for p in primes for q in primes for r in primes if (p**a)*(q**b)*(r**c) <= limit ]

But it is very slow because len(primes)(=5761455) is high.

Then I tried a very ugly code for printing values.
It generates all values for p < q < r (p, q, r primes)

1 Answer
1

global

there is no need to make primes a global. You only read from it, but don't assign to it, you can use it as is. It will be even faster if you make primes a local variable by passing it in as a parameter, so Python uses the LOAD_FAST bytecode instead of LOAD_GLOBAL. Since primes is called, indexed and sliced a lot, this can make a difference.

while condition

i1 < len(primes) and i2 < len(primes) and i3 < len(primes) and .... Since i1<i2<i3, only i3 < len(primes) is needed. If you use len(primes) so often, it pays to make it a local variable.

return, don't print

your method immediately prints the results. In general it is better to split the calculation and presentation, so to let the method return or yield the values, and another method do the presentation

looping

I suggest you watch the talk Loop like a Pro by David Baumgold. It's recommended material for every python programmer.

Instead of looping over the indices, you can loop over the primes-list immediately.

For p, and the first index (i), you can loop over enumerate(primes)

Then you can use this index i to slice primes to only include the elements with an index larger than p and go on to r, so you arrive at the following, naive implementation: