我有一个要求,我必须更新/合并字典的嵌套子级。我已经尝试过dict.update
,但是它会删除兄弟姐妹(在下面的示例中为get_users
)。
我可以更新tree['endpoints']['get_tickets']['handlers']['after'] = 'new_after_handler'
之类的字典,但是那些字典键是动态的,来自字符串,不知道如何实现?
所以我基本上想通过下面的测试,当然endpoints.get_tickets.handlers
是动态的。
def test_partial_merge(self):
source = {
"name": "tucktock",
"endpoints": {
"get_tickets": {
"path": "tickets",
"handlers": {
"after": "after_handler",
"after_each": "after_each_handler"
}
},
"get_users": {},
},
}
merging = {
"after": "new_after_handler",
}
expected = {
"name": "tucktock",
"endpoints": {
"get_tickets": {
"path": "tickets",
"handlers": {
"after": "new_after_handler",
"after_each": "after_each_handler"
}
},
"get_users": {},
},
}
merger = Merger()
result = merger.merge(source, merging, "endpoints.get_tickets.handlers")
self.assertEqual(expected, result)
答案 0 :(得分:2)
您可以执行以下操作:
source = {
"name": "tucktock",
"endpoints": {
"get_tickets": {
"path": "tickets",
"handlers": {
"after": "after_handler",
"after_each": "after_each_handler"
}
},
"get_users": {},
},
}
merging = {
"after": "new_after_handler",
}
expected = {
"name": "tucktock",
"endpoints": {
"get_tickets": {
"path": "tickets",
"handlers": {
"after": "new_after_handler",
"after_each": "after_each_handler"
}
},
"get_users": {},
},
}
def merge(a, b, dict_path): # modifies a in place
for key in dict_path:
a = a[key]
a.update(b)
merge(source, merging, "endpoints.get_tickets.handlers".split('.'))
print(source == expected)
>>> True
答案 1 :(得分:0)
在您的Merger.merge
方法中,您可以将source
转换为collections.defaultdict(dict)
。然后,您可以遍历第三个参数("endpoints.get_tickets.handlers".split('.')
),并迭代到所需的深度级别,然后更新此部分。
示例:
def merge(source, merging, path):
result = defaultdict(dict)
result.update(source)
current_part = result
for key in path.split('.'):
current_level = current_level[key]
current_level.update(merging)
return result