Python 查找列表列表中的最大重叠

Python 查找列表列表中的最大重叠,python,algorithm,list,overlap,Python,Algorithm,List,Overlap,我有两份清单: a = [[0, 1, 5], [2], [3], [4], [6, 7], [8, 9, 10, 11], [12], [13], [14], [15]] b = [[0, 1], [2, 3], [4], [5], [6, 7], [8, 9, 10, 11], [12], [13, 14], [15]] 如何找到列表值之间的最大重叠,并使用此最大重叠构建新的列表列表。 换句话说,我正在寻找一个函数f,它通过合并重叠列表来最大化列表大小 本例中函数f的预期结果为: f(a,

我有两份清单:

a = [[0, 1, 5], [2], [3], [4], [6, 7], [8, 9, 10, 11], [12], [13], [14], [15]]
b = [[0, 1], [2, 3], [4], [5], [6, 7], [8, 9, 10, 11], [12], [13, 14], [15]]
如何找到列表值之间的最大重叠,并使用此最大重叠构建新的列表列表。 换句话说,我正在寻找一个函数
f
,它通过合并重叠列表来最大化列表大小

本例中函数
f
的预期结果为:

f(a,b) = [[0, 1, 5], [2, 3], [4], [6, 7], [8, 9, 10, 11], [12], [13, 14], [15]] 

您可以使用的变体来解决此问题:对于每个列表,
[a,b,c]
a
b
统一,将
a
c
统一。对两个列表都执行此操作,然后导出结果根

我们可以修改一个简单的分离集算法:

from collections import defaultdict

def parent(u,mapping):
    if mapping[u] == u:
        return u
    mapping[u] = parent(mapping[u],mapping)
    return mapping[u]

def relation(array,mapping=None):
    if mapping is None:
        mapping = {}

    for e in array:
        if len(e) > 0:
            u = e[0]
            if u not in mapping:
                mapping[u] = u
            for v in e[1:]:
                if v not in mapping:
                    mapping[v] = v
                mapping[parent(u,mapping)] = parent(v,mapping)
    return mapping

def f(a,b):
    mapping = {}
    relation(a,mapping)
    relation(b,mapping)

    results = defaultdict(set)
    for u in mapping.keys():
        results[parent(u,mapping)].add(u)
    return [list(x) for x in results.values()]
结果没有排序,因为我们使用的是集合。尽管如此,如果需要,您可以通过将
f
更改为:

def f(a,b):
    mapping = {}
    relation(a,mapping)
    relation(b,mapping)

    results = defaultdict(set)
    for u in mapping.keys():
        results[parent(u,mapping)].add(u)
    return sorted([list(x) for x in results.values()],key=lambda t:t[0])

这个解决方案的好处是,如果
a
b
本身存在重叠,那么它也可以工作,并且您可以轻松地将解决方案推广到任意数量的列表(例如
a
b
c
)。

如果我理解正确,以下几点可以做到:

[l for l in a if not any(all(x in l2 for x in l) for l2 in b)] + 
[l for l in b if not any(all(x in l2 for x in l) for l2 in a)] + 
[l for l in a if l in b]
第一项产生
a
中的所有列表,这些列表不属于
b
中的列表;第二项产生
b
中的所有列表,这些列表是
a
中列表的注释部分;第三项产生所有列表,它们都在
a
b

对于您的示例,这将产生以下结果:

[[0, 1, 5], [2, 3], [13, 14], [4], [6, 7], [8, 9, 10, 11], [12], [15]]

你自己试过什么吗?比如说
a
包含
[1,2],[3,4]
b
包含
[2,3]
结果应该包含
[1,2,3,4]
?如果@WillemVanOnsem在评论中提到的情况是真的,那么为什么
[6,7],[8,9,10,11]
不作为
[6,7,8,9,10,11]出现呢
在所需的输出中?@moinuddinqadri因为没有桥接(
[7,8]
)我假设..@moinuddinqadri:b因为没有包含两个列表元素的列表。只有当两个列表中都有实例时,才能统一它们。我认为这并不总是生成可传递闭包。假设你有
a=[[1,2],[3,4],[5,6]
b=[[2,3],[4,5]
结果是
[[1,2],[3,4],[5,6],[2,3],[4,5]
,而预期结果是
[[1,2,3,4,5,6]
。。。
[l for l in a if not any(all(x in l2 for x in l) for l2 in b)] + 
[l for l in b if not any(all(x in l2 for x in l) for l2 in a)] + 
[l for l in a if l in b]
[[0, 1, 5], [2, 3], [13, 14], [4], [6, 7], [8, 9, 10, 11], [12], [15]]