title: Multiple nested loops equivalent replacement in python
body: <p>I have a simple dictionary of the form <code>D = {2: 4, 3: 2, 5: 1, 7: 1}</code>. There are 4 keys which are the primes and  4 values which represent the maximum power. Based on that I want to generate all combinations of the form : </p>
  
  <blockquote>
    <p>p1^range1 * p2^range2 * p3^range3 * p4^range4</p>
  </blockquote>
  
  <p>where <code>range1</code> to <code>range4</code> are the ranges corresponding to the values of the dictionary of each prime. For <code>p1 = 2</code> the range will be <code>range(0, 4+1)</code></p>
  
  <p>The most simplistic way would be a nested for loop with four levels :</p>
  
  <pre><code>for i1 in range(0, 4+1):
     for i2 in range(0, 2+1):
        for i3 in range(0, 1+1):
           for i4 in range(0, 1+1):
              n = 2**i1 * 3**i2 * 5**i3 * 7**i4
  </code></pre>
  
  <p>which is what I intend and it is correct but this is a non-elegant and mechanical way.</p>
  
  <p>Another way is to use the  <code>itertools.product</code> which works if all the ranges are the same. Basically it is as follows  :</p>
  
  <pre><code>for x in itertools.product(range(0, 4+1), repeat=4):
      print(x, end='   ')
  </code></pre>
  
  <p>However this will generate all the possible combinations including (2, 2, 3, 4), 
  (4, 4, 2, 3) or (2, 3, 4, 4) which are not valid in my case as the power of 5 (which is the third element in the tuple) will never be 3 and the power of 7 will never be 4. I want to limit somehow if possible the range of elements . So in this case the maximum tuple will be (4, 2, 1, 1) corresponding to the powers (values in dictionary D). So basically I need ONLY the range of tuples from (0,0,0,0) to (4,2,1,1). </p>
  
  <p>Is there a way to achieve this without using for loops and do it in a similar approach as with <code>itertools.product</code>?</p>
  
  <p>Many thanks in advance.</p>