我有多个json文件包含我需要合并的关系数据,每个文件都有一条记录,其中commonkey是所有文件中的公共密钥,在下面的示例中a0,a1是公共密钥。值是嵌套的如下所示,Key1,key2等多个键的字典,我需要合并多个json文件并获取dboutput.json中显示的输出,文件名作为合并操作中的索引。这样的问题是related question合并丢失的信息,但在我的情况下,我不希望任何更新替换现有的密钥或跳过更新,在点击现有密钥的情况下,创建另一个由文件名索引的嵌套字典,如图所示下面:
示例:
文件db1.json:
"a0": { "commonkey": [ "a1", "parentkeyvalue1" ], "key1": "kvalue1", "key2": "kvalue2" "keyp": "kvalue2abc" }, "a1": { ... }
文件db2.json:
"a0": { "commonkey": [ "a1", "parentkeyvalue1" ], "key1": "kvalue1xyz", "key2": "kvalue2", "key3": "kvalue2" }, "a1": { ... }
所需输出
文件dboutput.json
"a0": { "commonkey": [ "a1", "parentkeyvalue1" ], "key1": {"db1":"kvalue1","db2":"kvalue1xyz"} , "key2": {"db1":"kvalue2","db2":"kvalue2"} , "key3": {"db2":"kvalue2"} "keyp": {"db1":"kvalue2abc"} }, "a1": { ... }
那么如何做这种无损合并呢?注意“key2”:{“db1”:“kvalue2”,“db2”:“kvalue2”}即使键\值对相同,它们也需要单独存储。实际上,输出是所有输入文件的并集,并且具有来自所有其他文件的所有条目。
另外
"commonkey": [
"a1",
"parentkeyvalue1"
],
所有文件的都相同,因此无需重复
答案 0 :(得分:2)
我终于成功了:
class NestedDict(collections.OrderedDict):
"""Implementation of perl's autovivification feature."""
def __getitem__(self, item):
try:
return dict.__getitem__(self, item)
except KeyError:
value = self[item] = type(self)()
return value
def mergejsons(jsns):
##use auto vification Nested Dict
op=nesteddict.NestedDict()
for j in jsns:
jdata=json.load(open(j))
jname=j.split('.')[0][-2:]
for commnkey,val in jdata.items():
for k,v in val.items():
if k!='commonkey':
op[commnkey][k][jname]=v
if op[commnkey].has_key('commonkey'):
continue
else:
op[commnkey][k][jname]=v
答案 1 :(得分:1)
一个简单的解决方案是迭代每个JSON对象,并在每个“commonkey”中添加字典对。这是一个示例,您可以在列表中加载每个JSON文件,然后迭代合并它们。
#!/usr/bin/python
import json
# Hardcoded list of JSON files
dbs = [ "db1.json", "db2.json" ]
output = dict() # stores all the merged output
for db in dbs:
# Name the JSON obj and load it
db_name = db.split(".json")[0]
obj = json.load(open(db))
# Iterate through the common keys, adding them only if they're new
for common_key, data in obj.items():
if common_key not in output:
output[common_key] = dict(commonkey=data["commonkey"])
# Within each common key, add key, val pairs
# subindexed by the database name
for key, val in data.items():
if key != "commonkey":
if key in output[common_key]:
output[common_key][key][db_name] = val
else:
output[common_key][key] = {db_name: val}
# Output resulting json to file
open("dboutput.json", "w").write(
json.dumps( output, sort_keys=True, indent=4, separators=(',', ': ') )
)