如何将两个dict合并在一起,同时保持相同的结构但组合值



假设我有两个结构相同的dict(整个dict是任何一个dict的结构(:

{
'0': {
'A': a,
'B': b,
},
'1': {
'C': c,
'D': d,
}
}
#Sample input and output:
#dict1
{
'0': {
'A': 0,
'B': 1,
},
'1': {
'C': 2,
'D': 3,
}
}
#dict2
{
'0': {
'A': 5,
'B': 5,
},
'1': {
'C': 5,
'D': 5,
},
'3': { 'E': 5 } #this will be ignored when combining
}
#merged output with addition:
{
'0': {
'A': 5,
'B': 6,
},
'1': {
'C': 7,
'D': 8,
}
}

理想情况下,除了值a、b、c、d之外,两个dict的所有内容都是相同的。对于任何在结构中具有与第一个dict不同的部分的后续dict,在合并时会忽略这些部分。就像dict2中的3ANDE键在合并中被忽略一样。

如何将两个dict合并为一个dict,以保持相同的结构,但具有合并的值?我想让它通用,所以这个"合并"操作可以是加法、减法等。要合并的dict的数量也可以改变(一次不只是2个(。

谢谢,我希望从您的解决方案中了解更多关于Python的信息

你想要那种类型的代码吗

marged={}
for i in a:
for j in a[i]:
marged.setdefault(j,a[i].get(j))
print(marged)

输出:

{'A': 'a', 'B': 'b', 'K': 'k', 'L': 'l', 'C': 'c', 'D': 'd'}

输入:

a={
'0': {
'A': "a",
'B': "b",
'K':"k",
'L':"l"
},
'1': {
'C': "c",
'D': "d"
}
}

您可以简单地使用UPDATE方法。如果a是一本字典,并且你想添加另一本词典,那么说b。然后简单地使用

a.update(b)

这是将所有dict合并,即合并。

d = {
'0': {
'A': a,
'B': b,
},
'1': {
'C': c,
'D': d,
},
}
def merge(d):
merged_dict = {}
for k in d:
for key in d[k]:
if not merged_dict.get(key, False):
merged_dict[key] = d[k][key]
return merged_dict
md = merge(d)

这应该只是将不同的dict合并为一个。

为了支持任意dict结构和嵌套,您必须使用递归函数。将运算符作为参数传递,并使用例如reduce来计算所有传递的dict(一个或多个(的值。这只假设dicts中的dicts,但也可以处理例如具有另一个块if isinstance(first, list)的列表和相应的列表理解。

import functools, operator
def merge(op, first, *more):
if isinstance(first, dict):
return {key: merge(op, first[key], *(d[key] for d in more if key in d))
for key in first}for key in first}
else:
return functools.reduce(op, more, first)
A = {'0': {'A': 1, 'B':  2}, '1': {'C':  3, 'D':  4}}
B = {'0': {'A': 5, 'B':  6}, '1': {'C':  7, 'D':  8}}
print(merge(operator.add, A, B))
# {'0': {'A': 6, 'B': 8}, '1': {'C': 10, 'D': 12}}

也适用于两个以上的dict、不同的运算符,或者如果moredict的密钥多于或少于first:

C = {'0': {'A': 9, 'B': 10}, '1': {'C': 11, 'D': 12}}
D = {'0': {'A': 13, 'X': 14}, '2': {'C': 15, 'D': 16}}
print(merge(lambda x, y: f"{x}-{y}", A, B, C, D))
# {'0': {'A': '1-5-9-13', 'B': '2-6-10'}, '1': {'C': '3-7-11', 'D': '4-8-12'}}

然而,它仍然假设与firstmore中的相同键相对应的值具有相同的类型。

最新更新