Python:将JSON添加到现有JSON中

3
假设我有两个JSON文件。我希望能够加载这两个文件,然后将第二个文件的条目添加到第一个文件中。这可能包括添加字段或列表条目。类似于以下示例:
file1.json:
{ "fruit": [ { "name": "apple", "color": "red" }, { "name": "orange", "color": "orange" } ] }

file2.json:

{ "fruit": [ { "name": "strawberry", "color": "red", "size": "small" }, { "name": "orange", "size": "medium" } ] }

结果:

{ "fruit": [ { "name": "apple", "color": "red" }, { "name": "orange", "color": "orange", "size": "medium" }, { "name": "strawberry", "color": "red", "size": "small" } ] }

一开始,我考虑将它们加载到字典中,尝试使用 update 这样的方法:
    import simplejson
    
    filea = open("file1.json", 'r')
    dicta = simplejson.loads(filea.read())
    
    fileb = open("file2.json", 'r')
    dictb = simplejson.loads(fileb.read())
    
    filea.close()
    fileb.close()
    
    dicta.update(dictb)

由于两个字典都有“fruit”这个词条,我希望它们能够合并,但实际上它只是用dictb中的词条覆盖了dicta中的词条。

我意识到我可以编写循环代码来处理这个示例,但我正在使用的实际文件要大得多且更加复杂。在我重新发明轮子之前,我想知道是否已经有一个库可以做到这一点。值得一提的是,我正在使用Python 2.6.2。

感谢任何建议或建议!


所以你想要按照它们的“名称”值加入“fruit”的元素?你能控制JSON格式吗?如果file1和file2在其他字段中具有冲突数据(例如,都有一个“apple”的“颜色”),那么规则是什么? - Silas Ray
在这个特定的例子中,我想基于名称值“yes”进行连接。在现实生活中,必须匹配两个特定字段而不仅仅是一个,但概念类似。我对第二个文件的格式拥有完全控制,但对第一个文件则没有任何控制。不应该出现冲突,因此在这种情况下的行为可以是更容易的那个(例如使用新的覆盖旧的或保留旧的)。 - Matthew Pape
非常好的问题,很抱歉我之前没有提到。我正在使用Python 2.6.2,并已将其添加到原始帖子中。 - Matthew Pape
2个回答

6

你需要扩展列表检查每个值。Python无法知道你想基于字典的name项合并它们的方法:

def merge(lsta, lstb):
    for i in lstb:
        for j in lsta:
            if j['name'] == i['name']:
                j.update(i)
                break
        else:
            lsta.append(i)

for k,v in dictb.items():
    merge(dicta.setdefault(k, []), v)

因此,dicta变量将是:

{'fruit': [{'color': 'red', 'name': 'apple'}, 
           {'color': 'orange', 'name': 'orange', 'size': 'medium'},
           {'color': 'red', 'name': 'strawberry', 'size': 'small'}]}

1
我希望不必为json文件的格式编写特定的代码,因为它很容易改变。理想情况下,我希望有一个库或通用函数可以将任何两个json文件合并在一起。我想这太难了!尽管如此,这段代码完美地解决了我发布的示例,并展示了我将在更大更复杂的规模上需要做的基础工作。我希望它也能帮助其他面临类似问题的人。感谢您的回答! - Matthew Pape

0

给定一个解析后的 JSON 列表 parsed_json

transformed_data = []
for data in parsed_json:
    transformed_data.append({})
    for fruit in data['fruit']:
        fruit_copy = fruit.copy()
        transformed_data[-1][fruit_copy.pop('name')] = fruit_copy
merged_fruit = defaultdict(dict)
for name, values in transformed_data.iteritems():
    merged_fruit[name].update(values)

你可以在2.7+中使用字典推导式来完成,但你说你用的是2.6.2版本。鉴于你说在现实世界中,你要根据多个字段合并,你可以在设置transformed_data成员时更改键值为源数据中所需的任何字段。如果你不关心破坏原始解析数据,你也可以丢弃copy


我不得不稍微调整一下这段代码才能让它对我起作用,但最终它似乎解决了我发布的示例问题。我喜欢使用多个字段作为键的想法,但它仅适用于此基本的JSON结构。真实世界的情况涉及更复杂的包含列表等结构的结构...等等。我希望有一个库可以处理所有这些,但看起来最终我还是要为文件的特定格式编写代码。感谢您的帮助和提供的代码示例。 - Matthew Pape
@xaevinx 我可能错了,但这种东西在ORM之外很难找到。虽然许多人都需要做这样的事情,但是转换的逻辑对于每个场景来说都是如此的定制化,将行为概括成库将会很困难,而且可能比自己开发还要昂贵。 - Silas Ray
我认为一个通用的库可能不是最优的选择,但对我来说仍然是理想的。时间并不是什么大问题。唯一的问题是文件会继续变化,这将迫使代码每次都要改变。 - Matthew Pape

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接