Itertools.product 自定义每个输入的组合数量?

Posted

技术标签:

【中文标题】Itertools.product 自定义每个输入的组合数量?【英文标题】:Itertools.product to customize the amount of combos for each input? 【发布时间】:2016-10-25 23:18:53 【问题描述】:

我正在使用 itertools.product 提出组的组合。我不擅长在没有示例的情况下进行解释,所以这里是代码。

group1=[1,2,3];group2=[4,5,6];group3=[7,8,9]
list(itertools.product(group1,group2,group3))

这给了我每组 1 的所有组合。但是,我将如何获取第 1 组中的 2 个数字、第 2 组中的 2 个数字和第 3 组中的 1 个数字的组合?

例如,我希望组合 (1,2,5,6,9) 出现在列表中。可以自定义这个吗? itertools.product 似乎没有我需要的那么灵活,而且我在学习笛卡尔积以理解如何调整 .product 函数方面一直没有成功。

编辑:为了简单起见,我将组缩小,但每个组都有数百个唯一值。

【问题讨论】:

您需要[1, 2][5, 6][9]的产品或[1, 2, 5, 6, 9]的组合 如果 group1、group2 和 group3 都有 200 个元素,那么您将看到类似 79202000000 种不同的可能性,即使我们没有具体化它们,也无法迭代。你确定你问的是你真正需要的问题吗? 【参考方案1】:

取每组 r-组合的笛卡尔积:

from itertools import product, chain, combinations, permutations

groups = [[1,2,3],[4,5,6],[7,8,9]]
counts = (2, 2, 1)

selections = [combinations(g, c) for g, c in zip(groups, counts)]

for n_tuple in product(*selections):
    print(tuple(chain.from_iterable(n_tuple)))

输出:

(1, 2, 4, 5, 7)
(1, 2, 4, 5, 8)
(1, 2, 4, 5, 9)
(1, 2, 4, 6, 7)
(1, 2, 4, 6, 8)
(1, 2, 4, 6, 9)
(1, 2, 5, 6, 7)
(1, 2, 5, 6, 8)
(1, 2, 5, 6, 9)
(1, 3, 4, 5, 7)
(1, 3, 4, 5, 8)
(1, 3, 4, 5, 9)
(1, 3, 4, 6, 7)
(1, 3, 4, 6, 8)
(1, 3, 4, 6, 9)
(1, 3, 5, 6, 7)
(1, 3, 5, 6, 8)
(1, 3, 5, 6, 9)
(2, 3, 4, 5, 7)
(2, 3, 4, 5, 8)
(2, 3, 4, 5, 9)
(2, 3, 4, 6, 7)
(2, 3, 4, 6, 8)
(2, 3, 4, 6, 9)
(2, 3, 5, 6, 7)
(2, 3, 5, 6, 8)
(2, 3, 5, 6, 9)

如果从每个组中选择时顺序很重要(例如,如果(3, 2, 5, 6, 9)(2, 3, 5, 6, 9) 不同),您可以将combinations 更改为permutations

您应该注意,这会从N 组中生成choose(|g1|, c1) * choose(|g2|, c2) * ... * choose(|gN|, cN) 元素,其中choose(n, k) 是binomial coefficient。如果您的小组规模如您所说的那样有数百个,或者小组的数量也很大,那么这将是无法估量的。

【讨论】:

以上是关于Itertools.product 自定义每个输入的组合数量?的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用 itertools.product 时会出现 MemoryError?

用itertools.product简化嵌套for循环

算法:用itertools.product()简化嵌套for循环

Python的itertools.product 方法

itertools.product 比嵌套 for 循环慢

itertools.product - 返回列表而不是元组