Python 仅从另一个文件更新json文件的叶子

Python 仅从另一个文件更新json文件的叶子,python,json,Python,Json,我有一个Json文件(dataSchema),我想用另一个Json文件(data)的值填充叶子。 下面是两个输入文件的示例,以及我想要的输出 数据模式: "data": { "keyA": {}, "keyB": { "keyB1" : { "keyB11" : "" } }, "keyC": {}, "keyD": {}, "keyE": { "keyE1" : ""

我有一个Json文件(dataSchema),我想用另一个Json文件(data)的值填充叶子。 下面是两个输入文件的示例,以及我想要的输出

数据模式:

"data": {
    "keyA": {},
    "keyB": {
        "keyB1" : {
             "keyB11" : ""
         }
     },
    "keyC": {},
    "keyD": {},
    "keyE": {
        "keyE1" : ""
    }
}
数据:

"data": {
    "keyA": {
        "keyA1" : {
             "keyA11" : ValueA11,
             "keyA12" : ValueA12
         },
    },
    "keyB": {
        "keyB1" : {
             "keyB11" : ValueB11
         },
        "keyB2" : {
             "keyB21" : ValueB21
         },
        "keyB3" : {
             "keyB31" : ValueB31,
             "keyB32" : ValueB32
         }
     },
    "keyC": {
        "keyC1" : ValueC1
    },
    "keyD": {
        "keyD1" : {
             "keyD11" : ValueD11
         },
        "keyD2" : {
             "keyD21" : ValueD21
         }        
    },
    "keyE": {
        "keyE1" : {
             "keyE11" : {
                 "keyE111" : ValueE111,
                 "keyE112" : ValueE112
             },
             "keyE12" : ValueE12
         },
        "keyE2" : ValueE2
    }
}
我想要的是:

"data": {
    "keyA": {
        "keyA1" : {
             "keyA11" : ValueA11,
             "keyA12" : ValueA12
         },
    },
    "keyB": {
        "keyB1" : {
             "keyB11" : ValueB11
         }
     },
    "keyC": {
        "keyC1" : ValueC1
    },
    "keyD": {
        "keyD1" : {
             "keyD11" : ValueD11
         },
        "keyD2" : {
             "keyD21" : ValueD21
         }        
    },
    "keyE": {
        "keyE1" : {
             "keyE11" : {
                 "keyE111" : ValueE111,
                 "keyE112" : ValueE112
             },
             "keyE12" : ValueE12
         }
    }
}
我尝试使用更新功能,但它包含所有子键


有一种方法可以在elengant和short way中使用python实现这一点?

好吧,让我们在模式树上进行递归漫游:

def normalize(schema, data, result):
    for k in schema:
        value = schema[k]
        result[k] = value
        if not value or not isinstance(value, dict):
            # leaf
            if k in data:
                result[k] = data[k]
        elif k in data:
            normalize(schema[k], data[k], result[k])


rs = {}
normalize(schema, data, rs)
print json.dumps(rs, indent=2, sort_keys=True)

您可以使用递归来实现:

def is_leaf(v):
    return v == {} or not isinstance(v, dict)


def fill_leaves(schema, data):
    return {k: v if is_leaf(schema[k]) else fill_leaves(schema[k], data[k]) for k, v in data.items() if k in schema}
以下是与dict理解循环安装相同的功能(可读性更强):

def fill_leaves(schema, data):
    d_out = {}
    for k, v in data.items():
        if k in schema:
            if is_leaf(schema[k]):
                d_out[k] = v
            else:
                d_out[k] = fill_leaves(schema[k], data[k])
    return d_out