参数数量未知的手动产品

时间:2015-12-26 16:15:21

标签: python python-2.7 cartesian-product

以下示例给出了相同的结果:

一个。

product = []
for a in "abcd":
    for b in "xy":
        product.append((a,b))

from itertools import product
list(product("abcd","xy"))

当我不知道参数的数量时,我如何计算笛卡尔积?(如例A)?

原因我问这个:

考虑这段代码:

allocations = list(product(*strategies.values()))
for alloc in allocations:
    PWC[alloc] = [a for (a,b) in zip(help,alloc) if coalitions[a] >= sum(b)]

strategies字典的值是元组列表,help是辅助变量(每个alloc的长度相同的列表),coalitions是另一个分配给元组的字典,帮助一些数值。

由于策略值已排序,我知道if语句在某个alloc之后不再为真。由于分配是一个相当大的列表,如果我可以使用示例算法A,我将避免大量的比较和大量的总和。

2 个答案:

答案 0 :(得分:1)

你可以这样做:

items = ["abcd","xy"]

from itertools import product
list(product(*items))

列表items可以包含任意数量的字符串,并且product的计算将为您提供这些字符串的笛卡尔积。

请注意,您不必将其转换为列表 - 您可以迭代它并在您不再希望继续时停止:

for item in product(*items):
    print(item)
    if condition:
        break

答案 1 :(得分:0)

如果您只想在达到某个条件后中止分配,并且您想避免为这些元素生成笛卡尔积的所有元素,那么首先不要列出所有组合。

itertools.product lazy ,这意味着它一次只能生成笛卡尔积的单个值。因此,您永远不需要生成所有元素,也不需要比较元素。只是不要在结果上调用list(),因为这会迭代整个序列并将所有可能的组合存储在内存中:

allocations = product(*strategies.values())
for alloc in allocations:
    PWC[alloc] = [a for (a,b) in zip(help,alloc) if coalitions[a] >= sum(b)]

    # check whether you can stop looking at more values from the cartesian product
    if someCondition(alloc):
        break

重要的是要注意itertools.product如何生成值,它遵循什么模式。它基本上等同于以下内容:

for a in firstIterable:
    for b in secondIterable:
        for c in thirdIterable:
            …
                for n in nthIterable:
                    yield (a, b, c, …, n)

因此,您可以从迭代的左侧获得增加的模式。因此,请确保以可正确指定中断条件的方式对可迭代内容进行排序。