[Python]:生成所有可能组合的数组

Posted

技术标签:

【中文标题】[Python]:生成所有可能组合的数组【英文标题】:[Python]: generate and array of all possible combinations 【发布时间】:2016-08-16 15:41:09 【问题描述】:

我有一个非常简单的组合问题。我有两个数组(a 和 b)。数组 a 表示数组 b 中三个插槽之一可以取的所有值。数组 b 中的每个槽都可以有一个介于 1 和 5 之间的值。例如 [1, 4, 5]。我想生成一个包含所有可能组合的数组 (c)。我喜欢将基本示例扩展为更大的数组。

输入:

a = [1, 2, 3, 4, 5]
b = [1, 2, 3]

输出:

c = [[1, 1, 1], [1, 1, 2],[1, 1, 3], [1, 1, 4], [1, 1, 5],
     [1, 2, 1], [1, 2, 2],[1, 2, 3], [1, 2, 4], [1, 2, 5],
     [1, 3, 1], [1, 3, 2],[1, 3, 3], [1, 3, 4], [1, 3, 5],
     [1, 4, 1], [1, 4, 2],[1, 4, 3], [1, 4, 4], [1, 4, 5],
     [1, 5, 1], [1, 5, 2],[1, 5, 3], [1, 5, 4], [1, 5, 5],
     [2, 1, 1], [2, 1, 2],[2, 1, 3], [2, 1, 4], [2, 1, 5],
     [2, 2, 1], [2, 2, 2],[2, 2, 3], [2, 2, 4], [2, 2, 5],
     [2, 3, 1], [2, 3, 2],[2, 3, 3], [2, 3, 4], [2, 3, 5],
     [2, 4, 1], [2, 4, 2],[2, 4, 3], [2, 4, 4], [2, 4, 5],
     [2, 5, 1], [2, 5, 2],[2, 5, 3], [2, 5, 4], [2, 5, 5],
     [3, 1, 1], [3, 1, 2],[3, 1, 3], [3, 1, 4], [3, 1, 5],
     [3, 2, 1], [3, 2, 2],[3, 2, 3], [3, 2, 4], [3, 2, 5],
     [3, 3, 1], [3, 3, 2],[3, 3, 3], [3, 3, 4], [3, 3, 5],
     [3, 4, 1], [3, 4, 2],[3, 4, 3], [3, 4, 4], [3, 4, 5],
     [3, 5, 1], [3, 5, 2],[3, 5, 3], [3, 5, 4], [3, 5, 5],
     [4, 1, 1], [4, 1, 2],[4, 1, 3], [4, 1, 4], [4, 1, 5],
     [4, 2, 1], [4, 2, 2],[4, 2, 3], [4, 2, 4], [4, 2, 5],
     [4, 3, 1], [4, 3, 2],[4, 3, 3], [4, 3, 4], [4, 3, 5],
     [4, 4, 1], [4, 4, 2],[4, 4, 3], [4, 4, 4], [4, 4, 5],
     [5, 5, 1], [5, 5, 2],[5, 5, 3], [5, 5, 4], [5, 5, 5],
     [5, 1, 1], [5, 1, 2],[5, 1, 3], [5, 1, 4], [5, 1, 5],
     [5, 2, 1], [5, 2, 2],[5, 2, 3], [5, 2, 4], [5, 2, 5],
     [5, 3, 1], [5, 3, 2],[5, 3, 3], [5, 3, 4], [5, 3, 5],
     [5, 4, 1], [5, 4, 2],[5, 4, 3], [5, 4, 4], [5, 4, 5],
     [5, 5, 1], [5, 5, 2],[5, 5, 3], [5, 5, 4], [5, 5, 5]]

上述问题的解决方法:

d = []
for i in range(len(a)):
    for j in range(len(a)):
        for k in range(len(a)):
            e = []
            e.append(i+1)
            e.append(j+1)
            e.append(k+1)
            d.append(e)

我正在寻找一种更通用的方法。一种可以容纳更大的数组(见下文)而无需使用嵌套 for 循环结构的方法。我搜索了一个类似的例子,但在 *** 上找不到。

输入:

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

【问题讨论】:

看看pythonitertools。组合方法可以满足您的需求。 从你的描述来看,我也不认为b需要一个数组,只需要一个指定数组长度的整数值 我在对多个公差变量进行蒙特卡罗模拟时遇到了类似的问题,但我发现生成所有可能组合的数组没有意义,因为它是如此简单(请参阅您自己的代码)以动态生成这些组合。 在我看来,这更像是笛卡尔积而不是组合,在这种情况下,它是许多以前问题的重复。 @DSM 你说得对,应该是产品。 【参考方案1】:

您正在寻找itertools.product()

a = [1, 2, 3, 4, 5]
b = 3  # Actually, you just need the length of the array, values do not matter

c = itertools.product(a, repeat=b)

请注意,这会返回一个迭代器,您可能需要使用 list() 对其进行强制转换,但请注意,如果大小增加,这可能需要很长时间并且会大量消耗内存。

【讨论】:

【参考方案2】:

在一般情况下,您当然应该使用itertools 模块,在这种特殊情况下为itertools.product,如另一个答案中所述。

如果您想自己实现该函数,您可以使用递归使其适用于任何数组大小。此外,您可能应该将其设为生成器函数(使用yield 而不是return),因为结果可能会相当长。你可以试试这样:

def combinations(lst, num):
    if num > 0:
        for x in lst:
            for comb in combinations(lst, num - 1):
                yield [x] + comb
    else:
        yield []

【讨论】:

以上是关于[Python]:生成所有可能组合的数组的主要内容,如果未能解决你的问题,请参考以下文章

生成长度在给定范围内的数组的所有可能组合

生成所有可能的数组组合

如何生成字符之间带有空格的字符串的所有可能组合? Python

Python 轻松解决从 K 个字符串数组中任意取一个字符串,按顺序拼接,列出所有可能的字符串组合。(对比用库和不用库的方法)

生成所有可能的真/假组合

二维数组中长度为 8 的所有可能组合