我有两个JSON文件,一个包含一个完全定义的对象和多个嵌套级别,另一个包含同一对象的精简版本,只列出需要更改的元素
文件1示例
{
"toplevel": {
"value": {
"settings": [
{
"name": "A Default Value",
"region": "US",
"inner": {
"name": "Another Default",
"setting": "help"
}
}
]
}
}
}
文件2示例
{
"toplevel": {
"value": {
"settings": [
{
"name": "A Real Value",
"inner": {
"name": "Another Real Value",
}
}
]
}
}
}
我想将文件2中的更新合并到文件1中
我的输出应该是
{
"toplevel": {
"value": {
"settings": [
{
"name": "A Real Value",
"region": "US",
"inner": {
"name": "Another Real Value",
"setting": "help"
}
}
]
}
}
}
到目前为止我已经试过了
f1 = json_load(file1)
f2 = json_load(file2)
f1['toplevel']['value']['settings'][0].update(f2['toplevel']['value']['settings'][0].items())
它非常适合顶级项目,但显然它覆盖了整个“内部”对象,删除了其中的“设置”键
有没有办法遍历整个树并只替换非字典值?除了json和集合之外,我没有访问外部库的权限(对于有序dict)
这取决于你想要什么
解决方案1
如果只想用新字典替换所有值,可以使用以下选项:
这将导致:
或者,您可以使用
这将导致相同的结果,但将更新
file_1
解决方案2
如果您只想更新嵌套中的特定键,而保留所有其他值不变,那么可以使用递归来实现这一点。在您的示例中,您使用的是
dict
、list
和str
值。因此,我将使用相同的类型构建递归上述内容可能有点难以理解,但我会尽力解释。 有两种方法,一种是合并两个字典,另一种是尝试合并两个列表
合并词典
为了合并这两个字典,我检查了更新字典的所有键和值,因为这可能是两者中较小的一个
第一个块将新键放入原始字典,这是更新开始时不在原始字典中的值
第二个块正在更新嵌套值。在这里,我区分了三种情况:
dict
,则再次运行字典合并,但更深一层李>list
(或tuple
),请运行列表合并函数李>str
(或int
,float
),则用更新的值替换原始值李>合并列表
这比字典要复杂一点,因为列表没有可以比较的顺序或键。因此,我不得不做出一个沉重的假设,即
list
更新将始终包含相同的元素,请参阅如何处理具有多个元素的list
的限制由于
lists
的长度相同,我可以假设列表的索引是匹配的。现在,为了检查所有值是否相同,我们必须执行以下操作:list
(或tuple
),则列表合并李>str
(或int
,float
),则就地重写原始值李>结果
使用:
最终结果将是:
请注意,与第一个解决方案相比,值
'setting': 'help'
和'region': 'US'}
现在仍在原始字典中限制
由于相同的长度限制,如果不想更新列表中的元素,则必须传递相同的元素类型,但为空
有关如何忽略列表更新的示例:
相关问题 更多 >
编程相关推荐