Python-从长度不等的列表中获取替换的所有唯一组合

joe*_*son 3 python combinations list

注意:这不是重复的问题,因为标题可能会说

如果我有一个list列表,则需要从中获取所有组合并进行替换。

import itertools

l = [[1,2,3] ,[1,2,3],  [1,2,3]]
n = []
for i in itertools.product(*l):
    if sorted(i) not in n:
        n.append(sorted(i))
for i in n:
    print(i)

[1, 1, 1]
[1, 1, 2]
[1, 1, 3]
[1, 2, 2]
[1, 2, 3]
[1, 3, 3]
[2, 2, 2]
[2, 2, 3]
[2, 3, 3]
[3, 3, 3]
Run Code Online (Sandbox Code Playgroud)

感谢@RoadRunner和@Idlehands。

上面的代码完美,有两个问题:

  1. 对于较大的列表,itertools.product引发MemoryError。当l具有18个3个长度的子列表时,给出的合并数约为4亿。

  2. 订单很重要,因此sorted无法解决我的问题。对于某些人可能会造成混淆,因此请在下面的示例中进行说明。

    l = [[1,2,3], [1], [1,2,3]]

在这里,我有2个独特的群组:

组1:元素0、2具有相同的值[1,2,3]

第2组:元素1,其值为[1]

因此,我需要的解决方案是:

[1,1,1]
[1,1,2]
[1,1,3]
[2,1,2]
[2,1,3]
[3,1,3]
Run Code Online (Sandbox Code Playgroud)

因此位置1固定为1

希望这个例子有帮助。

Roa*_*ner 5

如何用a将具有相同元素的序列按不同顺序分组collections.defaultdict,然后从每个键中选择第一个元素:

from itertools import product
from collections import defaultdict

l = [[1] ,[1,2,3],  [1,2,3]]

d = defaultdict(list)
for x in product(*l):
    d[tuple(sorted(x))].append(x)

print([x[0] for x in d.values()])
Run Code Online (Sandbox Code Playgroud)

这使:

[(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 2, 2), (1, 2, 3), (1, 3, 3)]
Run Code Online (Sandbox Code Playgroud)

另外,也可以通过保留一组已添加的内容来完成此操作:

from itertools import product

l = [[1] ,[1,2,3],  [1,2,3]]

seen = set()
combs = []

for x in product(*l):
    curr = tuple(sorted(x))
    if curr not in seen:
        combs.append(x)
        seen.add(curr)

print(combs)
# [(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 2, 2), (1, 2, 3), (1, 3, 3)]
Run Code Online (Sandbox Code Playgroud)

如果您不想排序,请考虑使用frozensetwith collections.Counter()

from collections import Counter
from itertools import product

l = [[1] ,[1,2,3],  [1,2,3]]

seen = set()
combs = []

for x in product(*l):
    curr = frozenset(Counter(x).items())

    if curr not in seen:
        seen.add(curr)
        combs.append(x)

print(combs)
# [(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 2, 2), (1, 2, 3), (1, 3, 3)]
Run Code Online (Sandbox Code Playgroud)

注意:setdefault()如果您不想使用,也可以使用第一种方法defaultdict()