我将一堆应用程序设置存储在字典中,并以JSON格式保存到文本文件中。我想将它与一组默认的键/值合并,以便随着应用程序在将来发生变化,新的可以合并。例如:
defaults = {
'svn': "",
'notify': {
'email': "",
'notifo': { 'username': "", 'secret': ""},
'active': False,
'lastCheck': 0
}
}
local = {
'svn': "/path/to/trunk/",
'notify': {
'email': "me@mysite.com",
'notifo': { 'username': "me", 'secret': "1234"},
}
}
请注意,'local'缺少['notify'] ['active']和['notify'] ['lastCheck']。我希望能够将两个词典合并为一个看起来像这样的词典:
local = {
'svn': "/path/to/trunk/",
'notify': {
'email': "me@mysite.com",
'notifo': { 'username': "me", 'secret': "1234"},
'active': False,
'lastCheck': 0
}
}
我一直在寻找各处,但只看到人们压扁字典,合并第一级或用defaultdict做有趣的事情的例子。是否可以递归地合并嵌套的词典。
答案 0 :(得分:4)
我认为以下函数可能会执行您想要的操作,但我没有检查每个字典中所有可能的缺失键组合。此外,这可能不适用于大型dicts:
import types
def merge(x,y):
# store a copy of x, but overwrite with y's values where applicable
merged = dict(x,**y)
xkeys = x.keys()
# if the value of merged[key] was overwritten with y[key]'s value
# then we need to put back any missing x[key] values
for key in xkeys:
# if this key is a dictionary, recurse
if type(x[key]) is types.DictType and y.has_key(key):
merged[key] = merge(x[key],y[key])
return merged
通过将合并函数和以下位放在文件test.py
中,它似乎适用于您的示例,以及我为复杂性添加的一些额外项目:
defaults = {
'svn': "",
'notify': {
'email': "",
'notifo': { 'username': "", 'secret': ""},
'active': False,
'lastCheck': 0
},
'test': "another test"
}
local = {
'svn': "/path/to/trunk/",
'notify': {
'email': "me@mysite.com",
'notifo': { 'username': "me", 'secret': "1234", 'notx': 39},
},
'test2': 'again a test'
}
print merge(defaults,local)
并且运行给出:
$ python test.py
{'svn': '/path/to/trunk/', 'test2': 'again a test', 'notify': {'lastCheck': 0, 'notifo': {'username': 'me', 'secret': '1234', 'notx': 39}, 'active': False, 'email': 'me@mysite.com'}, 'test': 'another test'}