假设我有以下代码来收集所有可能的组合。
abArray = []
for a in range(minA, maxA, aStep):
for b in range(minB, maxB, bStep):
if a < b: continue
abArray.append((a,b))
有没有一种更有效的方法来存储所有可能的条件组合,而不是使用嵌套的 for 循环?
假设我有以下代码来收集所有可能的组合。
abArray = []
for a in range(minA, maxA, aStep):
for b in range(minB, maxB, bStep):
if a < b: continue
abArray.append((a,b))
有没有一种更有效的方法来存储所有可能的条件组合,而不是使用嵌套的 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])
首先,您可以使用生成器而不是显式列表。如果您只是要迭代它们,您可能不需要存储所有组合。其次,您可以缩短内部循环:
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...
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 的解决方案。只有开始使用更多变量和各种交互约束时,这种方法的真正威力才会变得明显。