如何合并在python中附加两个嵌套的词典?

时间:2013-07-25 12:23:00

标签: python dictionary

例如,我有两个词:

schema = {
    'type': 'object',
    'properties': {
        'reseller_name': {
            'type': 'string',
        },
        'timestamp': {
            'type': 'integer',
        },
    },
    'required': ['reseller_name', 'timestamp'],
}

schema_add = {
    'properties': {
        'user_login': {
            'type': 'string',
        },
    },
    'required': ['user_login'],
}

如何将下一个与附加结果dict合并:

schema_result = {
    'type': 'object',
    'properties': {
        'reseller_name': {
            'type': 'string',
        },
        'timestamp': {
            'type': 'integer',
        },
        'user_login': {
            'type': 'string',
        },
    },
    'required': ['reseller_name', 'timestamp', 'user_login'],
}

规则:

示例中propertiesrequired的{​​{1}}和scheme路径相同。

  1. 如果两个dict都有相同路径的dicts,则它们会使用相同的规则合并。
  2. 如果两个dict都有相同路径的列表,则添加第二个列表。
  3. 如果两个dict都具有相同路径的简单值(或dict和非dict或list和non list),则第一个值将覆盖第二个。
  4. 如果只有一个dict具有某个路径的键,则设置此键和值。

4 个答案:

答案 0 :(得分:2)

不确定问题的位置,但是你把它写下来的方式几乎就像一个计算机程序,这个例子就像一个测试用例。你为什么不从这开始?

def add_dict(d1, d2):
    newdict = {}
    for (key, value) in d1.iteritems():
        if key in d2: ...
            #apply rules, add to newdict, use 
        else:
            #simply add
    for (key, value) in d2.iteritems():
        if not key in d1:
            # simply add
    return newdict

这可能写得更紧密,但可能更容易编辑。

编辑..在写完最后一条评论后,忍不住编写了一个更好的实现

def merge_values(a,b):
    if a==None or b==None:
        return a or b
    # now handle cases where both have values
    if type(a)==dict:
        return add_dict(a, b)
    if type(a)==list:
        ...

def add_dict(d1,d2):
    return dict(
        [
            (key,
             merge_values(
                 d1.get(key,None),
                 d2.get(key,None)))
            for key
            in set(d1.keys()).union(d2.keys())
        ])

答案 1 :(得分:2)

我自己的解决方案 @ Nicolas78 帮助:

def merge(obj_1, obj_2):
    if type(obj_1) == dict and type(obj_2) == dict:
        result = {}
        for key, value in obj_1.iteritems():
            if key not in obj_2:
                result[key] = value
            else:
                result[key] = merge(value, obj_2[key])
        for key, value in obj_2.iteritems():
            if key not in obj_1:
                result[key] = value
        return result
    if type(obj_1) == list and type(obj_2) == list:
        return obj_1 + obj_2
    return obj_2

答案 2 :(得分:2)

我正在添加此问题的简单解决方案。假设样本数据不会改变。

def merge_nested_dicts(schema,schema_add):
    new_schema = schema
    for k in schema:
        if k in schema_add.keys():
            if isinstance(schema_add[k],dict):
                new_schema[k].update(schema_add[k])
            if isinstance(schema_add[k],list):
                new_schema[k] = new_schema[k]+schema_add[k]
    return new_schema

答案 3 :(得分:0)

如果您完全了解密钥,请尝试此操作。

schema['properties'].update(schema_add['properties'])
schema['result'].append(schema_add['result'])

结果在模式中合并。

如果您不完全知道密钥,则需要一个循环来查找内部列表和字典。

for value in schema:
    if value is dict:
        if schema_add.has_key(value) and schema_add[value] is dict:
            schema[value].update(schema_add[value])
    elif value is list:
        if schema_add.has_key(value) and schema_add[value] is list:
            schema[value].append(schema_add[value])

结果也可以合并到不同的字典中。