合并具有公共元素的字典中的列表

时间:2017-05-17 14:09:13

标签: python list python-3.x dictionary merge

如果共享至少一个元素的值(列表),我想合并字典的键和值。

输入将是:

dico = {"a" : [1,2,3], "b":[9,2,89], "c":[3,12,530],"d":[34,42],"e":[34,6]}

我希望这样的事情是这样的:

{"a,b,c" : [1,2,3,9,89,12,530], "d,e": [34,42,6] }

我尝试过的都没有......你认为这是可能的吗?

1 个答案:

答案 0 :(得分:1)

您使用Union-Find aka Disjoin Set方法。首先,您需要两个功能:unionfind。我经常把那些躺在某处的人保留,以防我需要它们。

def find(x):
    l = leaders[x]
    if l is not None:
        l = find(l)
        leaders[x] = l
        return l
    return x

def union(x, y):
    lx, ly = find(x), find(y)
    if lx != ly:
        leaders[lx] = ly

现在,您可以使用这些来确定列表中每个元素的一个“领导者”......

dico = {"a" : [1,2,3], "b":[9,2,89], "c":[3,12,530],"d":[34,42],"e":[34,6]}
leaders = collections.defaultdict(lambda: None)

for val in dico.values():
    for other in val[1:]:
        union(val[0], other)        

...然后将具有相同“领导者”的元素分组到组中。

groups = collections.defaultdict(set)
for x in leaders:
    groups[find(x)].add(x)

现在,还要按照第一要素的领导者对键进行分组:

keys = collections.defaultdict(list)
for key in dico:
    keys[find(dico[key][0])].append(key)

最后汇总结果。

result = {','.join(ks): groups[leader] for (leader, ks) in keys.items()}
# {'d,e': {42, 34, 6}, 'c,a,b': {1, 2, 3, 9, 12, 530, 89}}

请注意,这是使用集合而不是列表。如果您需要保留原始订单,只需将密钥分组,然后将各自的列表放在一起。