【问题标题】:Union Multiple Nested JSONs in Python在 Python 中联合多个嵌套 JSON
【发布时间】:2013-10-08 18:30:13
【问题描述】:

我有多个包含需要合并的关系数据的 json 文件,每个文件都有一条记录,其中 commonkey 是所有文件中的公共键,在下面的示例中 a0 ,a1 是公共键。值是嵌套的如下所示的多个键的字典,如 Key1、key2 等,我需要合并多个 json 文件并得到输出,如 dboutput.json 所示,文件名作为合并操作中的索引。这样的问题是一个related question,它合并了丢失的信息,但在我的情况下,我不想要任何替换现有键或跳过更新的更新,以防点击现有键,创建另一个由文件名索引的嵌套字典,如下所示:

例子:

文件 db1.json:

“a0”:{ “公鸡”:[ "a1", “父键值 1” ], "key1": "kvalue1", “key2”:“kvalue2” “keyp”:“kvalue2abc” }, “a1”:{ ... }

文件 db2.json:

“a0”:{ “公鸡”:[ "a1", “父键值 1” ], "key1": "kvalue1xyz", "key2": "kvalue2", “key3”:“kvalue2” }, “a1”:{ ... }

期望的输出

文件 dboutput.json

“a0”:{ “公鸡”:[ "a1", “父键值 1” ], "key1": {"db1":"kvalue1","db2":"kvalue1xyz"} , "key2": {"db1":"kvalue2","db2":"kvalue2"} , "key3": {"db2":"kvalue2"} “keyp”:{“db1”:“kvalue2abc”} }, “a1”:{ ... }

那么如何进行这种无损合并呢?注意 "key2": {"db1":"kvalue2","db2":"kvalue2"} 即使 key\value 对相同,它们也需要单独存储。实际上,输出是所有输入文件的联合,并包含所有其他文件的所有条目。

还有

"commonkey": [
            "a1", 
            "parentkeyvalue1"
        ],

所有文件都相同,因此无需重复

【问题讨论】:

  • 您对待键 "a0""commonkey""key2" 不同
  • @JanneKarila 你能说得清楚点吗?
  • 我指出您在所需的输出中没有"commonkey": {"db1": ["a1","parentkeyvalue1"], "db2": ["a1","parentkeyvalue1"]}。程序如何知道哪些键可以合并哪些不可以?
  • @JanneKarila 因为 commonkey 很常见,不能重复,所有文件都一样

标签: python json dictionary merge union


【解决方案1】:

一个简单的解决方案是遍历每个 JSON 对象,并在您看到的每个“通用键”中添加字典对。这是一个示例,您将每个 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=(',', ': ') )
)

【讨论】:

  • +1 谢谢,我已经使用带有 vivification 的嵌套 dict 解决了类似的问题
【解决方案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

【讨论】:

    猜你喜欢
    • 2014-10-22
    • 1970-01-01
    • 2023-01-29
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 2012-09-09
    • 2017-08-24
    • 1970-01-01
    相关资源
    最近更新 更多