在Python中获得多个范围内的所有可能组合的最佳方法是什么?

2024-09-28 18:49:04 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

有没有比使用嵌套for循环更有效的方法来存储带有条件的所有可能的组合?你知道吗


Tags: 方法代码inforifrangecontinueappend
3条回答

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的解决方案。只有当您开始使用更多变量和各种交互约束时,这种方法的真正威力才会显现出来。你知道吗

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

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...

我想你在找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])

相关问题 更多 >