在Python中联合多个嵌套JSON

时间:2013-10-02 11:25:34

标签: python json dictionary merge union

我有多个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"
        ],
所有文件的

都相同,因此无需重复

2 个答案:

答案 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=(',', ': ') )
)