如何从所有排列中生成所有可能的组合?

时间:2016-03-11 20:02:33

标签: python permutation

我在Python中列出了K元素的所有排列,如下所示:

import itertools
perms = list(itertools.permutations(range(K), K))

我想生成这些排列M的所有可能组合的矩阵(或列表)perms。该矩阵(或列表)的每个元素的大小为N。我怎么能这样做?

例如,对于K=2,我会得到perms=[(0, 1), (1, 0)]。对于N=3,我希望:

M = [ [(0, 1), (0, 1), (0, 1)],
      [(0, 1), (0, 1), (1, 0)],
      [(0, 1), (1, 0), (0, 1)],
      [(0, 1), (1, 0), (1, 0)],
      [(1, 0), (0, 1), (0, 1)],
      [(1, 0), (0, 1), (1, 0)],
      [(1, 0), (1, 0), (0, 1)],
      [(1, 0), (1, 0), (1, 0)] ]

M是一个包含8个列表的列表。每个列表的大小为N=3,其中包含perms的元素。

对于N=2,我想:

M = [ [(0, 1), (0, 1)],
      [(0, 1), (1, 0)],
      [(1, 0), (0, 1)],
      [(1, 0), (1, 0)] ]

对于N=1,我希望:

M = [ [(0, 1), (1, 0)] ] = perms

我不知道我是否正确地表达了我的问题(我认为它可以比这更清楚地重新制定)。

2 个答案:

答案 0 :(得分:3)

考虑到这一点,可能有一种非常简单的方法可以使用itertools.combinationsset来获得所需的结果:

import itertools
K = 2
N = 3
perms = list(itertools.permutations(range(K), K))
# The order matters so we need to copy the list N times
perms = perms*N 
# Create the combinations
combs = itertools.combinations(perms, N)
# Only keep unique combinations
M = set(combs)

如果您想将其作为列表列表使用:

M = [list(i) for i in M]
然后

返回

[[(1, 0), (0, 1), (0, 1)],
 [(1, 0), (1, 0), (1, 0)],
 [(0, 1), (0, 1), (1, 0)],
 [(0, 1), (1, 0), (1, 0)],
 [(0, 1), (0, 1), (0, 1)],
 [(0, 1), (1, 0), (0, 1)],
 [(1, 0), (0, 1), (1, 0)],
 [(1, 0), (1, 0), (0, 1)]]

答案 1 :(得分:3)

您可以使用product中的itertools

from itertools import permutations, product

perms = permutations(range(2))
cartesian_tuples = product(perms, repeat=3)

# (((0, 1), (0, 1), (0, 1)),
#  ((0, 1), (0, 1), (1, 0)),
#  ((0, 1), (1, 0), (0, 1)),
#  ((0, 1), (1, 0), (1, 0)),
#  ((1, 0), (0, 1), (0, 1)),
#  ((1, 0), (0, 1), (1, 0)),
#  ((1, 0), (1, 0), (0, 1)),
#  ((1, 0), (1, 0), (1, 0)))

如果您需要多次迭代任何内容,可以手动将各个部分转换为列表。当前结构由生成器组成,这些生成器将在一次迭代后耗尽并且不能再次使用。如果您想要嵌套列表:

cartesian_tuples = map(list, list(product(perms, repeat=3)))

# [[(0, 1), (0, 1), (0, 1)],
#  [(0, 1), (0, 1), (1, 0)],
#  [(0, 1), (1, 0), (0, 1)],
#  [(0, 1), (1, 0), (1, 0)],
#  [(1, 0), (0, 1), (0, 1)],
#  [(1, 0), (0, 1), (1, 0)],
#  [(1, 0), (1, 0), (0, 1)],
#  [(1, 0), (1, 0), (1, 0)]]

在Python 3.X中,您必须将此包装在另一个列表调用中,因为map(...)会返回map个对象。

cartesian_tuples = list(map(list, list(product(perms, repeat=3))))

或者,你可以避免所有这些废话并使用列表理解。

cartesian_tuples = [[perm for perm in prod] for prod in product(perms, repeat=3)]

但是每次需要时都可以创建一个新的迭代器。

def product_of_permutations(n, k):
    return product(permutations(range(k)), repeat=n)