0

假设我有以下代码来收集所有可能的组合。

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

有没有一种更有效的方法来存储所有可能的条件组合,而不是使用嵌套的 for 循环?

4

3 回答 3

7

我想你正在寻找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

首先,您可以使用生成器而不是显式列表。如果您只是要迭代它们,您可能不需要存储所有组合。其次,您可以缩短内部循环:

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)

然后稍后:

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

Joel 的答案是最简单的,但可能效率低下(它会生成所有可能的组合,然后剔除那些与约束不匹配的组合)。

Ned 的效率更高,但您必须手动编码所有循环和约束。

如果您有多个范围,您可能希望查看该constraint模块:

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()]

请注意,这不是一个很好的例子;由于只有在所有基础变量都已知后才能评估功能约束,所以这基本上等同于 Joel 的解决方案。只有开始使用更多变量和各种交互约束时,这种方法的真正威力才会变得明显。

于 2012-07-01T14:48:31.000 回答