我有两个列表列表:
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]]
答案 0 :(得分:7)
您可以使用disjoint-set structure的变体来解决此问题:对于每个列表[a,b,c]
,您统一 a
b
和{ {1}} a
。您对两个列表执行此操作,然后派生结果根。
Here我们可以修改一个简单的 disjunct-set 算法:
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(a,b)
[[2, 3], [4], [0, 1, 5], [6, 7], [8, 9, 10, 11], [12], [13, 14], [15]]
来轻松地在每个元组的第一个元素上对它进行排序:
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])
此解决方案的优点在于,如果>>> f(a,b)
[[0, 1, 5], [2, 3], [4], [6, 7], [8, 9, 10, 11], [12], [13, 14], [15]]
或a
本身中存在重叠,它也可以正常工作,您可以轻松地将解决方案概括为使用任意数量的列表(例如b
,a
和b
)。
答案 1 :(得分:0)
当我理解正确时,以下将会这样做:
[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]]