如何批量删除JSON中未包含指定全部键的对象及关联数据?
问题描述
需要删除JSON文件中未同时包含"transaction_date"、"asset_description"、"asset_type"、"type"和"amount"全部键的完整对象,同时同步删除"first_name"中对应索引的数据,代码需适配任意数量的条目。
示例输入JSON
{ "first_name": { "0": "Thomas", "1": "John" }, "transactions": { "0": [ { "transaction_date": "11/29/2022", "asset_description": "FireEye, Inc.", "asset_type": "Stock", "type": "Sale (Partial)", "amount": "$1,001 - $15,000" } ], "1": [ { "scanned_pdf": true, "ptr_link": "https://efdsearch.senate.gov/search/view/paper/658E53E8-7C2C", "date_recieved": "01/30/2013" } ] } }
尝试的代码(未达到预期)
import json with open("xxxtester.json", "r") as f_in: data = json.load(f_in) to_delete = {"scanned_pdf", "ptr_link", "date_recieved"} for k in data["transactions"]: data["transactions"][k] = [ {kk: vv for kk, vv in d.items() if kk not in to_delete} for d in data["transactions"][k]] open("xxxtester.json", "w").write( json.dumps(data, indent=4))
期望输出
{ "first_name": { "0": "Thomas" }, "transactions": { "0": [ { "transaction_date": "11/29/2022", "asset_description": "FireEye, Inc.", "asset_type": "Stock", "type": "Sale (Partial)", "amount": "$1,001 - $15,000" } ] } }
解决方案
你原来的代码是过滤单条交易里的指定键,而非删除整个不符合条件的索引条目,所以会留下空对象。需要更换思路,直接筛选出符合要求的索引,再同步清理first_name对应数据。
基础实现代码(匹配示例需求)
import json # 定义必须同时存在的键集合 required_keys = {"transaction_date", "asset_description", "asset_type", "type", "amount"} with open("xxxtester.json", "r") as f_in: data = json.load(f_in) # 收集所有符合条件的索引:索引下至少有一个交易包含全部必填键 valid_indices = [] for idx, transactions_list in data["transactions"].items(): has_valid = any(required_keys.issubset(tx.keys()) for tx in transactions_list) if has_valid: valid_indices.append(idx) # 过滤transactions和first_name,只保留有效索引的内容 data["transactions"] = {idx: data["transactions"][idx] for idx in valid_indices} data["first_name"] = {idx: data["first_name"][idx] for idx in valid_indices} # 写入处理后的文件 with open("xxxtester.json", "w") as f_out: json.dump(data, f_out, indent=4)
进阶实现(支持单索引下过滤无效交易)
如果需要保留索引,但只删除该索引下不符合条件的交易对象(若过滤后索引下无交易则删除整个索引),可以用以下代码:
import json required_keys = {"transaction_date", "asset_description", "asset_type", "type", "amount"} with open("xxxtester.json", "r") as f_in: data = json.load(f_in) valid_indices = [] for idx, transactions_list in data["transactions"].items(): # 过滤当前索引下的交易,只保留符合条件的对象 filtered_tx = [tx for tx in transactions_list if required_keys.issubset(tx.keys())] if filtered_tx: data["transactions"][idx] = filtered_tx valid_indices.append(idx) # 清理无效索引的条目 data["transactions"] = {idx: data["transactions"][idx] for idx in valid_indices} data["first_name"] = {idx: data["first_name"][idx] for idx in valid_indices} with open("xxxtester.json", "w") as f_out: json.dump(data, f_out, indent=4)
代码说明
- 必填键检查:用
required_keys.issubset(tx.keys())快速判断单个交易对象是否包含所有必填键。 - 有效索引收集:遍历所有索引,标记出符合要求的索引,确保后续过滤时
transactions和first_name同步。 - 数据过滤:通过字典推导式直接保留有效索引对应的内容,避免修改原字典时出现遍历异常。
内容的提问来源于stack exchange,提问作者kie_codes
相关产品推荐
相关产品推荐

