1

たとえば、次の 2 つの辞書があります。

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です。schemescheme_add

  1. 両方の dict に同じパスの dict がある場合、それらは同じルールでマージされます。
  2. 両方の dict に同じパスのリストがある場合は、最初のリストを 2 番目に追加します。
  3. 両方の dict に同じパスを持つ単純な値 (または dict と non dict または list と non list) がある場合、最初の値が 2 番目の値で上書きされます。
  4. このキーと値を設定するよりも、パスを持つキーを持つ辞書が 1 つだけの場合。
4

4 に答える 4

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())
        ])
于 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 に答える