合并嵌套字典(默认值)

3

可能是重复问题:
python: 字典嵌套合并

我将一堆应用程序设置存储在一个字典中,并将其保存为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做有趣的事情。是否可能递归合并嵌套字典。

1个回答

4
我认为下面的函数可能会实现你想要的功能,但我没有检查每个字典中缺少键的所有可能组合。此外,这个函数可能不适用于大型字典:
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'}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接