如果共享至少一个元素的值(列表),我想合并字典的键和值。
输入将是:
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] }
我尝试过的都没有......你认为这是可能的吗?
答案 0 :(得分:1)
您使用Union-Find aka Disjoin Set方法。首先,您需要两个功能:union
和find
。我经常把那些躺在某处的人保留,以防我需要它们。
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}}
请注意,这是使用集合而不是列表。如果您需要保留原始订单,只需将密钥分组,然后将各自的列表放在一起。