如何从所有排列中生成所有可能的组合?
Posted
技术标签:
【中文标题】如何从所有排列中生成所有可能的组合?【英文标题】:How to generate all possible combinations from all permutations? 【发布时间】:2016-03-11 20:02:33 【问题描述】:我有一个 Python 中 K
元素的所有排列的列表,如下所示:
import itertools
perms = list(itertools.permutations(range(K), K))
我想为这些排列perms
的所有可能组合生成一个矩阵(或列表)M
。该矩阵(或列表)的每个元素的大小为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
我不知道我是否正确地表述了我的问题(我认为它可以比这更清楚地重新表述)。
【问题讨论】:
为什么不[(1,0), (1,0), (0,1)]
?当您指定N
时,当K
小于N
时,您如何决定如何填充列表?
那是我犯的错误。我将不得不接受一个答案并重新提出我认为的问题。
更新您的问题。
【参考方案1】:
您可以从itertools
使用product
。
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)
【讨论】:
感谢您的帮助。我很感激。我在这个问题上犯了一个错误。请查看编辑。【参考方案2】:考虑一下,可能有一种非常简单的方法可以使用itertools.combinations
和set
获得所需的结果:
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)]]
【讨论】:
感谢您的帮助。我很感激。我在这个问题上犯了一个错误。请查看编辑。以上是关于如何从所有排列中生成所有可能的组合?的主要内容,如果未能解决你的问题,请参考以下文章