我有一组数字[1, 2, 4, 1]
。现在,我想从这组大小为k(示例k = 3)生成所有可能的组合。所有生成的输出集不得重复
示例:[1, 2, 1]
和[2, 1, 1]
是相同的集合,但不应选择它们。只应出现其中一个。是否可以在Python中使用itertools的组合?
import itertools
x = [1, 2, 1]
print([p for p in itertools.product(x, repeat=3)])
我尝试过使用itertools.product,但它不起作用,使用itertools的组合得到了重复
我尝试过使用itertools.combinations print([p for p in set(itertools.combinations(x, r=3))])
如果我给出以下输入
x = [-1, 0, 1, 2, -1, -4]
为r = 3生成的输出是
[(0, -1, -4), (-1, -1, -4), (-1, 1, -4), (0, 2, -1), (-1, 0, 2), (-1, 2, -4), (0, 1, 2), (2, -1, -4), (-1, 0, -1), (0, 1, -4), (1, 2, -4), (-1, 0, 1), (-1, 1, 2), (0, 2, -4), (-1, 1, -1), (-1, 2, -1), (1, 2, -1), (0, 1, -1), (-1, 0, -4), (1, -1, -4)]
(-1, 0, 1)
和(0, 1, -1)
是具有相同组合的重复集。我不知道如何克服这一点。
这些被称为multisets,我们可以很容易地获得这些与sympy
模块的组合。
from sympy.utilities.iterables import multiset_combinations
list(multiset_combinations([1, 2, 4, 1], 3))
[[1, 1, 2], [1, 1, 4], [1, 2, 4]]
以下是@EdedkiOkoh的例子:
x = [-1, 0, 1, 2, -1, -4]
list(multiset_combinations(x, 3))
[[-4, -1, -1],
[-4, -1, 0],
[-4, -1, 1],
[-4, -1, 2],
[-4, 0, 1],
[-4, 0, 2],
[-4, 1, 2],
[-1, -1, 0],
[-1, -1, 1],
[-1, -1, 2],
[-1, 0, 1],
[-1, 0, 2],
[-1, 1, 2],
[0, 1, 2]]
您可以使用python的set datatype删除这些重复项,因为集合只包含唯一的组合:
import itertools as it
x = [-1, 0, 1, 2, -1, -4]
permutations = [p for p in set(it.combinations(x, r=3))]
print(permutations)
输出:
[(0, 1, 2),
(-1, 1, -1),
(-1, 2, -1),
(0, -1, -4),
(-1, -1, -4),
(-1, 1, -4),
(-1, 2, -4),
(2, -1, -4),
(1, 2, -4),
(-1, 0, 1),
(1, 2, -1),
(-1, 0, -4),
(-1, 0, 2),
(-1, 0, -1),
(-1, 1, 2),
(0, 2, -4),
(0, 2, -1),
(0, 1, -4),
(1, -1, -4),
(0, 1, -1)]
然后使用可以使用以下行:
unique_permutations = set(tuple(sorted(t)) for t in permutations)
输出:
{(-4, -1, -1),
(-4, -1, 0),
(-4, -1, 1),
(-4, -1, 2),
(-4, 0, 1),
(-4, 0, 2),
(-4, 1, 2),
(-1, -1, 0),
(-1, -1, 1),
(-1, -1, 2),
(-1, 0, 1),
(-1, 0, 2),
(-1, 1, 2),
(0, 1, 2)}
如何通过使用组合的frozenset
结果键入字典来获取组合然后仅采用独特的组合。这只会在创建dictionary
之前使用生成器。
combs1, combs2 = itertools.tee(itertools.combinations(x, r=3))
res = list(dict(zip(map(frozenset, combs1), combs2)).values())