Python合并目录多JSON文件时update()仅保留最后一个字典的问题
问题描述
我有一个包含多个JSON文件的目录,每个JSON文件的结构如下:
{
"resourceType": "Single",
"type": "transaction",
"entry": [
{"fullUrl": "urn:uuid", ...}, ...
]
}
每个文件包含3个顶层字典元素,我想要读取所有文件并将内容合并到一个主字典中,但运行以下代码后,主字典仅保留最后一个JSON文件的内容,长度始终为3,不清楚为什么update()每次读取文件后都会“重置”字典:
import os import json def json_read(): pathToDir = '/path/to/directory' json_mstr = {} for file_name in [file for file in os.listdir(pathToDir) if file.endswith('.json')]: with open(pathToDir + file_name) as input_file: print(file_name) json_str = json.load(input_file) json_mstr.update(json_str) print(len(json_mstr)) return json_mstr
问题原因
Python字典的update()方法逻辑是用新字典的键值对覆盖原有键值对:如果新字典与主字典存在相同键,主字典中该键的值会被新值替换;如果是新键,则追加到主字典中。
你的每个JSON文件顶层键完全一致(resourceType、type、entry),因此每次循环调用update()时,当前文件的三个键值对都会覆盖主字典的旧值,最终主字典只会保留最后一个文件的内容,长度自然为3。
解决方案
根据这类场景的常见需求,以下提供两种可行方案:
方案1:合并所有文件的entry数组(推荐)
假设所有文件的resourceType和type值固定一致,仅需合并entry数组:
import os import json def json_read(): pathToDir = '/path/to/directory' json_mstr = {'entry': []} for file_name in [file for file in os.listdir(pathToDir) if file.endswith('.json')]: # 用os.path.join避免路径拼接时的分隔符问题 with open(os.path.join(pathToDir, file_name)) as input_file: json_str = json.load(input_file) # 首次循环初始化固定键 if not json_mstr.get('resourceType'): json_mstr['resourceType'] = json_str['resourceType'] json_mstr['type'] = json_str['type'] # 合并entry数组 json_mstr['entry'].extend(json_str['entry']) print(len(json_mstr['entry'])) # 打印合并后的entry总数 return json_mstr
方案2:区分不同文件的键(若文件存在不同顶层键)
如果需要保留所有文件的顶层键并区分来源,可给键添加文件名前缀:
import os import json def json_read(): pathToDir = '/path/to/directory' json_mstr = {} for file_name in [file for file in os.listdir(pathToDir) if file.endswith('.json')]: with open(os.path.join(pathToDir, file_name)) as input_file: json_str = json.load(input_file) # 给每个键添加文件名前缀 for key, value in json_str.items(): json_mstr[f"{file_name.split('.')[0]}_{key}"] = value print(len(json_mstr)) return json_mstr
内容的提问来源于stack exchange,提问作者user2966197
相关产品推荐
相关产品推荐

