如何在 Python 中合并两个多深度对象

how to merge two multi-depth objects in python

提问人:Gavriel 提问时间:10/24/2023 最后编辑:Danila GancharGavriel 更新时间:10/24/2023 访问量:35

问:

我正在构建一些需要配置的应用程序,其中包含许多相似之处和一些差异。我希望能够使用一些基本配置并在需要时用特定值覆盖它。

每个 config 元素都是一个配置列表,每个配置都是一个 dict,可以将 dict 或数组作为值。我希望能够以一种“聪明”的方式合并它们。即:

base_conf = [
  {'a': 'foo', 'b': 12, 'c': {'x': 1, 'y': 2}, 'd': [1, 2, 3]},
  {'a': 'bar', 'd': [10, 20]}
]

conf = {
  'conf1': smart_merge(base_conf, [
    {'b': 24, 'c': {'y': 20}},
    {'c': {'x': 10, 'z': 30}}
  ]),
}

conf1 的预期结果是:

conf1: [
  {'a': 'foo', 'b': 24, 'c': {'x': 1, 'y': 20}, 'd': [1, 2, 3]},
  {'a': 'bar', 'c': {'x': 10, 'z': 30}, 'd': [10, 20]}
]

因此,目标再次是合并类型的嵌套对象:字典、列表、字符串和数字。它总是添加或覆盖,从不删除。

JSON的 列表 字典 合并

评论

2赞 Daviid 10/24/2023
你尝试过什么,你得到了什么结果?

答:

0赞 Daviid 10/24/2023 #1

我认为这不适用于以下情况:

{'c': {'x': 10, 'z': {'h': 1, 'j': 9}}}

因为嵌套有 2 个级别,所以我把它留给你:D

base_conf = [
  {'a': 'foo', 'b': 12, 'c': {'x': 1, 'y': 2}, 'd': [1,2,3]},
  {'a': 'bar', 'd': [10,20]}
]

add_to_base = [
    {'b': 24, 'c': {'y': 20}},
    {'c': {'x': 10, 'z': 30}}
  ]

# Initialize an empty list to store the merged dictionaries
result = []

# This is short and pretty
# but it doesn't work because instead of 
#     'c': {'x': 1, 'y': 20}
# we end upt with
#     'c': {'y': 20}
#
# for base_config_row, add_config_row in zip(base_conf, add_to_base):
#   result.append({**base_config_row, **add_config_row})

# We'll process row by row
for base_config_row, add_config_row in zip(base_conf, add_to_base):
    # Copy were we update values based on add_config_row
    merged_dict = base_config_row.copy()
    for key, value in add_config_row.items():
        if key in merged_dict and isinstance(value, dict) and isinstance(merged_dict[key], dict):
            # If it's a dictionary update it's values with what add_config_row might have (e.g add_to_base['c'])
            merged_dict[key].update(value)
        else:
            # if number or string or list simply overwrite (e.g add_to_base['b'])
            merged_dict[key] = value
    #Save updated config row
    result.append(merged_dict)


print(result)

这有效,它不是真正的功能,但您可以自己解决。