合并深度为2的两个嵌套字典的智能方法是什么?

时间:2015-03-16 17:13:54

标签: python python-3.x dictionary

什么是最好的"合并深度为2的两个嵌套字典的方法?

例如,我想合并以下两个词典:

dicA: - user1 {name,age,sex}
      - user2 {name,age,sex}

dicB  - user1 {location,job}
      - user3 {location,job}

为了得到:

dic_merged - user1 {name,age,sex,location,job}
           - user2 {name,age,sex}
           - user3 {location,job}

请注意,dicA和dicB中的子值始终是不相交的。 目前,我正在使用:

def merge(dicA,dicB):
    for user in dicB:
        if user in dicA:
            dicA[user].update(dicB[user])
        else:
            dicA[user] = dicB[user]
    return dicA

是否有替代更新或可以合并嵌套字典的单行程?

2 个答案:

答案 0 :(得分:1)

您可以使用dict comprehension(部分底部):

def merge(d1, d2):
     return {key: dict(d1.get(key, {}).items() + d2.get(key, {}).items()) for key in d1.keys() + d2.keys()}

这会创建一个包含在字典理解中使用的所有键的列表,并使用更健壮的dict.get来防止错误,如果键只在dict s中的一个。


对于Python 3 dict view对象是从dict.keys()dict.items()返回的,因此您可以使用itertools.chain(或包裹在dict view中的每个list对象中1}}):

def merge(d1, d2):
     return {key: dict(chain(d1.get(key, {}).items(), d2.get(key, {}).items())) for key in chain(d1.keys(), d2.keys())}

注意:使用collections.defaultdict(dict)可以让整个事情变得更好。

答案 1 :(得分:0)

我不认为你的建议方式有太多错误,不过我会使用try...except条款:

dicA = {'user1': { 'name': 'John', 'age': 45, 'sex': 'M'},
        'user2': { 'name': 'Jane', 'age': 42, 'sex': 'F'}}

dicB = {'user1': {'job': 'janitor', 'location': 'HK'},
        'user3': {'job': 'Python-wrangler', 'location': 'NY'}}

def merge(dicA,dicB):
    for user, d in dicB.items():
        try:
            dicA[user].update(dicB[user])
        except KeyError:
            dicA[user] = d
    return dicA

然后,结果为dicA

    {'user1': {'job': 'janitor', 'age': 45, 'name': 'John',
     'location': 'HK', 'sex': 'M'},
     'user2': {'age': 42, 'name': 'Jane', 'sex': 'F'},
     'user3': {'job': 'Python-wrangler', 'location': 'NY'}}