简体   繁体   English

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

[英]How to generate all possible combinations from all permutations?

I have a list of all permutations of K elements in Python like this: 我列出了Python中K元素的所有排列,如下所示:

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

I would like to generate a matrix (or list) M of all possible combinations of these permutations perms . 我想生成这些排列perms的所有可能组合的矩阵(或列表) M Each element of this matrix (or list) is of size N . 该矩阵(或列表)的每个元素的大小为N How can I do this? 我怎样才能做到这一点?

For example, for K=2 , I would get perms=[(0, 1), (1, 0)] . 例如,对于K=2 ,我将获得perms=[(0, 1), (1, 0)] For N=3 , I would like to have: 对于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 is a list that has 8 lists. M是具有8列表的列表。 Each list is of size N=3 and contains elements from perms . 每个列表的大小为N=3并包含来自perms元素。

For N=2 , I would like to have: 对于N=2 ,我想拥有:

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

And for N=1 , I would like to have: 对于N=1 ,我想拥有:

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

I do not know if I formulate my problem correctly (I think it can be re-formulated more clearly than this). 我不知道我是否正确地提出了我的问题(我认为可以比这更清晰地重新制定它)。

Thinking about it there might be a very simple way to get your desired result using itertools.combinations together with set : 考虑这一点,可能有一种非常简单的方法可以使用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)

If you want to have it as list of lists use: 如果要将其作为列表列表,请使用:

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

returns then 然后返回

[[(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)]]

You can use product from itertools . 您可以使用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)))

You can manually convert individual parts into lists if you need to iterate over anything more than once. 如果您需要多次迭代,则可以将各个零件手动转换为列表。 The current structure is composed of generators that will be exhausted after one iteration and cannot be used again. 当前的结构由生成器组成,生成器将在一次迭代后耗尽,无法再次使用。 If you want nested lists: 如果要嵌套列表:

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)]]

In Python 3.X, you will have to wrap this in another list call because map(...) returns a map object. 在Python 3.X中,您必须将其包装在另一个列表调用中,因为map(...)返回一个map对象。

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

Or, you can avoid all that nonsense and use a list comprehension. 或者,您可以避免所有的废话,而使用列表推导。

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

But it might just be better to create a new iterator each time you need one. 但是,每次需要一个新的迭代器可能会更好。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM