1

例如我有两个字典:

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'],
}

我如何才能将下一个与附加结果字典合并:

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

规则:

相同的路径是propertiesand requiredfor schemeand scheme_addin example。

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

4 回答 4

2

Not sure where the problem likes, but the way you're writing it down is almost like a computer program, and the example is like a test case. Why don't you start from this?

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

This can probably be written more tightly, but might be easier like that to edit.

Edit.. after writing the last comment, couldn't help but write a nicer implementation

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())
        ])
于 2013-07-25T12:30:44.390 回答
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
于 2013-07-25T14:00:55.467 回答
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
于 2014-07-17T09:41:13.603 回答
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])

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

于 2014-07-22T08:00:52.327 回答