0

Suppose I have the following code to collect all the possible combinations.

abArray = []
for a in range(minA, maxA, aStep):
  for b in range(minB, maxB, bStep):
    if a < b: continue
    abArray.append((a,b))

Is there a more efficient way to store all possible combinations with a condition rather than using nested for loops?

4

3 に答える 3

7

I think you're looking for itertools.product:

from itertools import product
abGenerator = product(range(minA, maxA, stepA), range(minB, maxB, stepB))
abArray = (i for i in abGenerator if i[0] < i[1])
于 2012-07-01T02:26:54.113 に答える
2

First, you can use a generator instead of an explicit list. You may not need to store all the combinations if you are just going to iterate over them. Second, you can cut short the inner loop:

def range_combos(minA, maxA, aStep, minB, maxB, bStep):
  for a in range(minA, maxA, aStep):
    for b in range(minB, min(a, maxB), bStep):
      yield (a,b)

then later:

for a, b in range_combos(...):
    # etc...
于 2012-07-01T02:26:59.823 に答える
1

Joel's answer is the simplest, but may be inefficient (it generates all possible combinations, then culls those that do not match the constraint).

Ned's is much more efficient, but you have to hand-encode all the loops and constraints.

If you have more than a few ranges, you may wish to look at the constraint module:

import constraint

p = constraint.Problem()
p.addVariable('a', range(minA, maxA, aStep))
p.addVariable('b', range(minB, maxB, bStep))
p.addConstraint(lambda a,b: a >= b, ['a','b'])

abArray = [(sol['a'], sol['b']) for sol in p.getSolutionIter()]

Note that this is not a good example; as a functional constraint can only be evaluated once all basis variables are known, this is essentially equivalent to Joel's solution. The real power of this approach only becomes evident once you start using more variables and a variety of interacting constraints.

于 2012-07-01T14:48:31.000 に答える