如何用Python移除JSON文件中满足日期条件的字典
解决JSON数组中移除天数差为0的条目问题
问题描述
现有一个JSON数组文件,需要实现逻辑:计算每个条目中date字段(终止日期)与当前日期的天数差,当天数差为0时,移除该条目并将结果写回原JSON文件。已实现计数器逻辑,但无法正确移除目标字典。
JSON示例
[ { "Name": "bla", "Lastname": "ftr", "date": "20/12/2023" }, { "Name": "dfas", "Lastname": "fsae", "date": "18/12/2023" }, { "Name": "john", "Lastname": "rapper", "date": "18/11/2023" } ]
原代码问题分析
- 代码1的问题:
countdown函数中break语句后代码无法执行,逻辑错误;- 使用
range(len(data))遍历列表并手动修改索引i,容易因列表长度变化导致索引越界或漏处理; - 仅打印提示,未实现移除条目及写回文件的逻辑。
- 代码2的问题:
- 仅移除了每个条目中的
date键,而非整个字典条目,不符合需求。
- 仅移除了每个条目中的
解决方案代码
from datetime import datetime import json def remove_expired_entries(): # 读取JSON文件 with open('tst.json', 'r') as f: data = json.load(f) today = datetime.now().date() # 筛选出天数差不为0的条目(保留未过期的) filtered_data = [] for entry in data: try: # 将字符串日期转为date对象 last_day = datetime.strptime(entry["date"], '%d/%m/%Y').date() # 计算终止日期与今天的天数差 day_diff = (last_day - today).days if day_diff != 0: filtered_data.append(entry) except ValueError: # 处理日期格式错误的情况,可选保留或跳过 filtered_data.append(entry) print(f"日期格式错误:{entry['date']}") # 将筛选后的结果写回JSON文件 with open('tst.json', 'w') as f: json.dump(filtered_data, f, indent=4) print(f"已移除{len(data)-len(filtered_data)}个过期条目") # 执行函数 remove_expired_entries()
关键说明
- 日期比较:使用
date()方法只比较日期部分,避免因时分秒差异导致天数计算错误; - 安全筛选:通过新建列表
filtered_data存储符合条件的条目,避免遍历原列表时修改导致的异常; - 错误处理:加入
try-except捕获日期格式错误,防止程序崩溃; - 写回文件:使用
json.dump时添加indent=4保持JSON格式美观。
结合计数器的完整逻辑
如果需要结合倒计时功能,当某个条目的天数差变为0时立即移除,可以修改为循环检测的版本:
from datetime import datetime import json import time def check_and_remove_expired(): while True: with open('tst.json', 'r') as f: data = json.load(f) today = datetime.now().date() filtered_data = [] expired_count = 0 for entry in data: last_day = datetime.strptime(entry["date"], '%d/%m/%Y').date() day_diff = (last_day - today).days if day_diff == 0: expired_count +=1 print(f"移除过期条目:{entry['Name']} {entry['Lastname']}") else: filtered_data.append(entry) print(f"{entry['Name']} 剩余天数:{day_diff}") if expired_count >0: with open('tst.json', 'w') as f: json.dump(filtered_data, f, indent=4) # 每小时检查一次,可根据需求调整间隔 time.sleep(3600) # 启动检测 check_and_remove_expired()
内容的提问来源于stack exchange,提问作者gamer25845
相关产品推荐
相关产品推荐

