使用Python在更大的列表中查找兼容列表

时间:2018-10-25 11:01:19

标签: python list set

大家好,谢谢您阅读我的问题。

所以基本上我有一个列表或集合的列表,其中包含从0到n的值。

一个列表的例子是n = 4。

L1 = [0, 1, 3, 4]

我有一个更大的列表,其中包含它们。例如:

L = [L1, L2, L3, ..., Lm]

我要做的是创建所有可能兼容的子集的列表,这些子集之间没有交集。

例如,如果我有:

L1 = [0, 1, 2] and L2 = [3, 4, 5, 6, 7]

这两个被认为是兼容的,因为它们的交集为空。

我已经编写了此函数,该函数接受此类列表的列表,并检查它们之间是否全部兼容。

def areListsCompatible(list):
     o = set(list[0])
     for i in range(1, len(list)):
         o = o & set(list[i])
         if(bool(o)==True):
             return False
return True

现在我的问题是如何编写一个包含列表的函数,并找到兼容列表的所有可能组合,两个列表可以兼容,三个甚至四个兼容?

我正在考虑递归,但似乎无法正确完成。

有帮助吗?谢谢。

编辑:

有人要求我输入和输出示例。

输入:

L = [[0, 1, 2], [3, 4, 5], [0, 1], [2, 3], [6, 7]]

输出:

O = [[[0, 1, 2], [3, 4, 5], [6, 7]], #O1
     [[0, 1], [3, 4, 5], [6, 7]],    #O2
     [[0, 1], [2, 3], [6, 7]],       #O3
     ...
    ]

依此类推...

1 个答案:

答案 0 :(得分:3)

以下递归生成器函数应该起作用。我相信性能可以提高。

def subsets(lsts):
    if not lsts:
        return
    for i, lst in enumerate(lsts):
        yield [lst]
        s = set(lst)
        pool = [x for x in lsts[i+1:] if not s.intersection(x)]
        for subs in subsets(pool):
            yield [lst] + subs

>>> L = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]]
>>> list(subsets(L))
[[[0, 1]], 
 [[0, 1], [2, 3]], 
 [[0, 1], [2, 3], [4, 5]], 
 [[0, 1], [3, 4]], 
 [[0, 1], [4, 5]], 
 [[1, 2]], 
 [[1, 2], [3, 4]], 
 [[1, 2], [4, 5]], 
 [[2, 3]], 
 [[2, 3], [4, 5]], 
 [[3, 4]], 
 [[4, 5]]]

如果您只想要完整的子集列表(不能将其他子集添加到列表),则可以进行一些细微调整:

def subsets(lsts, make_unique=True, used=None):
    if not lsts:
        yield []
    used = set(used or [])
    if make_unique:
        lsts = sorted(map(list, set(map(tuple, lsts))))
    for i, lst in enumerate(lsts):
        s = set(lst)
        pool = [x for x in lsts if not s.intersection(x)]
        for subs in subsets(pool, make_unique=False, used=used):
            if not used.intersection(map(tuple, subs)):
                yield [lst] + subs
            used.add(tuple(lst))

>>> list(subsets(L))
[[[0, 1], [2, 3], [4, 5]], 
 [[0, 1], [3, 4]], 
 [[1, 2], [3, 4]], 
 [[1, 2], [4, 5]]]
>>> L = [[0, 1, 2], [3, 4, 5], [0, 1], [2, 3], [6, 7]]
>>> list(subsets(L))
[[[0, 1], [2, 3], [6, 7]], 
 [[0, 1], [3, 4, 5], [6, 7]], 
 [[0, 1, 2], [3, 4, 5], [6, 7]]]