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。
上面的代码完美,有两个问题:
对于较大的列表,itertools.product引发MemoryError。当l具有18个3个长度的子列表时,给出的合并数约为4亿。
订单很重要,因此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。
希望这个例子有帮助。
如何用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()。