这是一个说明问题的例子......
a = {
"foo" : 2,
"bar" : 3,
}
b = {
"bar" : 4,
"zzz" : 5,
}
print(json.dumps(dict(a, **b), indent=4))
这会给你以下结果......
{
"foo": 2,
"bar": 4,
"zzz": 5
}
请注意"foo"
中的a
键是如何添加到结果中的?
现在看看这个例子......
a = {
"foo" : {
"1" : {
"foo" : True,
},
"2" : {
"foo" : True,
},
"3" : {
"foo" : True,
},
"4" : {
"foo" : True
}
}
}
b = {
"foo" : {
"1" : {
"foo" : True,
},
"2" : {
"foo" : True,
},
"3" : {
"foo" : False,
}
}
}
print(json.dumps(dict(a, **b), indent=4))
这会给你以下结果......
{
"foo": {
"1": {
"foo": true
},
"3": {
"foo": false
},
"2": {
"foo": true
}
}
}
"3"
已更新,就像上一个示例中"bar"
的更新方式一样,但请注意"4"
中的a
键未添加到结果中,如何"foo"
1}}在上一个例子中?
所以我的预期输出是:
{
"foo": {
"1": {
"foo": true
},
"3": {
"foo": false
},
"2": {
"foo": true
},
"4": {
"foo": true
}
}
}
如何修改此词典联合进程,以便保留a
中不在b
中的键?
我的总体目标是让我的字典a
,但b
中的任何值都会被覆盖。
答案 0 :(得分:2)
让我们来谈谈这种行为。我认为关键点是**kwargs
的工作原理。
在第一种情况下,当您将**b
传递给dict()
时,它与dict(a, bar=4, zzz=5)
相同。因此,在这种情况下,{zzz: 5}
被添加到字典中,{bar: 4}
已更新。
但在第二种情况下,当您将**b
传递给dict()
时,它与dict(a, foo={...})
相同。由于foo
参数会覆盖a
中的相同键,因此结果与b
完全相同。因此,这不是更新操作,而是覆盖操作。
再举一个例子:
a = {
"foo" : {
"1" : {
"foo" : True,
},
"2" : {
"foo" : True,
},
"3" : {
"foo" : True,
},
"4" : {
"foo" : True
}
}
}
b = {
"foo" : {
"1" : {
"foo" : True,
},
"2" : {
"foo" : True,
},
"3" : {
"foo" : False,
},
"5" : {
"foo" : False,
}
}
}
print(json.dumps(dict(a, **b), indent=4))
output:
{
"foo": {
"1": {
"foo": true
},
"2": {
"foo": true
},
"3": {
"foo": false
},
"5": {
"foo": false
}
}
}
答案 1 :(得分:1)
对于您的特定情况,只有dict
深度为1,您可以使用循环并调用dict.update()
来更新值。您无法工作的原因是dict(a, **b)
会覆盖共有的所有重复密钥a
和b
,并且仅保留b
&#39 ; s,表示a
"foo"
完全被b
' s "foo"
import json
for k in a.keys():
try:
a[k].update(b[k])
except KeyError:
continue
print(json.dumps(a, indent=4))
这将从"1" ,"2" ,"3"
dict
和b
"4"
dict
保持更新所需的结果a
。但是如果你有一个n深度的词典,那将无法正常工作。您将需要使用递归函数,如下所示:
示例数据:
a = {
"foo" : {
"1" : {
"foo" : {"1": True,
"2": False},
},
"2" : {
"foo" : True,
},
"3" : {
"foo" : True,
},
"4" : {
"foo" : True
}
},
}
b = {
"foo" : {
"1" : {
"foo" : {"1": True,
"3": True},
},
"2" : {
"foo" : True,
},
"3" : {
"foo" : False,
}
}
}
递归代码:
import json
def update(dctA, dctB):
if isinstance(dctA, dict) and isinstance(dctB, dict):
for k in set(dctA.keys()) & set(dctB.keys()):
update(dctA[k], dctB[k])
try:
dctA[k].update(dctB[k])
dctB.pop(k)
except (KeyError, AttributeError):
continue
return dctA
print(json.dumps(update(a, b), indent=4))
输出将是:
{
"foo": {
"1": {
"foo": {
"1": true,
"2": false,
"3": true
}
},
"2": {
"foo": true
},
"3": {
"foo": false
},
"4": {
"foo": true
}
}
}
您可以看到,"3"
密钥已更新,"foo"
更改为false
,"4"
保持为dict
{{1} }没有更新密钥b
。此外,由于递归函数,嵌套的"4"
键也已更新,"foo"
{"1": True, "2": False}
已更新为{"1": True, "3": True}
。 {"1": true, "2": false, "3": true}
保持不变,"1"
被保留,因为"2"
dict
没有密钥b
,密钥"2"
已创建,因为它是目前在"3"
dict
。