合并字典与子词典

时间:2017-08-31 06:32:08

标签: python dictionary data-structures merge python-3.6

我想深入合并2个字典,这两个字典在某个级别上具有相同键的一个或多个字典值。我怎样才能简单地合并那些内部词典?像“**”符号,但深度合并。

示例:

d1 = {"v1": "value1", "sub": {"sv1": "sub value 1"}}
d2 = {"v2": "value2", "sub": {"sv2": "sub value 2"}}
d3 = {**d1, **d2}
print(d3)

实际结果:

{'v1': 'value1', 'sub': {'sv2': 'sub value 2'}, 'v2': 'value2'}

期望的结果:

{'v1': 'value1',
 'sub': {'sv1': 'sub value 1', 'sv2': 'sub value 2'},
 'v2': 'value2'}

注意到子 - > sv1 - >子值1

这是一个简单的例子,而真实案例有几个级别的词典。此外,解决方案需要是通用的,因为词典的结构在高级中是未知的。

3 个答案:

答案 0 :(得分:1)

您已经有了使用所有常用密钥创建 d3 的前三个步骤:

>>> d1 = {"v1": "value1", "sub": {"sv1": "sub value 1"}}
>>> d2 = {"v2": "value2", "sub": {"sv2": "sub value 2"}}
>>> d3 = {**d1, **d2}  # initial merge of common keys

只需要一个后续步骤即可合并所有" sub"输入:

>>> for d in (d1, d2): # merge the "sub" entries
        d3['sub'].update(d['sub'])

这给出了期望的结果:

>>> d3
{'v1': 'value1', 'sub': {'sv2': 'sub value 2', 'sv1': 'sub value 1'}, 'v2': 'value2'}

希望这会有所帮助: - )

答案 1 :(得分:1)

for python3:

d1 = {"v1": "value1", "sub": {"sv1": "sub value 1",'newsub':"value 2",'newsubdict':{'ok':'pssible','not_again':{'key1':'just checking'}}}}
d2 = {"v2": "value2", "sub": {"sv2": "sub value 2",'newsubdict':{'fine':'i am working','not_again':{'key2':'Am i right?'}}}}

from copy import deepcopy
d3 = deepcopy(d1)

def combine_key(d2,d3):
  for key in d2.keys():
      if(key in d3):
              d3[key] =d2[key]
      elif(isinstance(d3[key],dict)):
              combine_key(d2[key],d3[key])
      else:
              d3[key].update(d2[key])

combine_key(d2,d3)
print(d3) #{'v1': 'value1', 'sub': {'sv1': 'sub value 1', 'newsub': 'value 2', 'newsubdict': {'ok': 'pssible', 'not_again': {'key1': 'just checking', 'key2': 'Am i right?'}, 'fine': 'i am working'}, 'sv2': 'sub value 2'}, 'v2': 'value2'}

答案 2 :(得分:1)

我最后写了这个:

import collections
import copy

def deep_dict_merge(dct1, dct2, override=True) -> dict:
    """
    :param dct1: First dict to merge
    :param dct2: Second dict to merge
    :param override: if same key exists in both dictionaries, should override? otherwise ignore. (default=True)
    :return: The merge dictionary
    """
    merged = copy.deepcopy(dct1)
    for k, v2 in dct2.items():
        if k in merged:
            v1 = merged[k]
            if isinstance(v1, dict) and isinstance(v2, collections.Mapping):
                merged[k] = deep_dict_merge(v1, v2, override)
            elif isinstance(v1, list) and isinstance(v2, list):
                merged[k] = v1 + v2
            else:
                if override:
                    merged[k] = copy.deepcopy(v2)
        else:
            merged[k] = copy.deepcopy(v2)
    return merged