You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python如何根据日期是否超X个月从字典列表中移除对应字典

问题根因

你原代码的问题本质是遍历列表的同时动态删除元素,正序遍历下删除元素后后续元素的索引会整体前移,但循环计数还是按原始长度递增,必然出现漏删、索引越界两个问题。另外用180天近似6个月的判断逻辑不符合业务规则,不同自然月的天数差、闰年都会导致判断误差。

最优实现:列表推导式过滤

列表推导式里完全可以直接做字符串转日期的解析,没有语法限制,这也是Python中过滤列表的标准写法,完全规避索引相关问题:

from dateutil import parser
from dateutil.relativedelta import relativedelta
from datetime import datetime

gp_clinicals_meds_repeat = session["gp_clinicals_meds_repeat"]
# 计算6个月前的时间截断点,严格符合按6个月判断的规则
cutoff = datetime.now() - relativedelta(months=6)

# 遍历原列表,仅保留日期不早于截断点的条目
gp_clinicals_meds_repeat["GpRepeatMedicationsList"] = [
    entry for entry in gp_clinicals_meds_repeat["GpRepeatMedicationsList"]
    if parser.parse(entry["Date"]) >= cutoff
]

# 同步更新总条数字段,保证结构数据一致
gp_clinicals_meds_repeat["TotalItemCount"] = len(gp_clinicals_meds_repeat["GpRepeatMedicationsList"])

这个方案的优势:

  • 无索引异常、漏删问题:遍历过程基于原列表生成新列表,和原列表的修改操作完全隔离
  • 逻辑直白可维护:筛选条件直接写在推导式里,一眼就能看懂过滤规则
  • 时间判断准确:用relativedelta做月份差值计算,不会出现硬编码180天带来的误差,比如1月31日加6个月是7月31日,用天数计算无法正确处理这种跨月的日期边界

如果业务规则确实要求按180天而非自然月判断,只需要把截断点的计算替换为cutoff = datetime.now() - timedelta(days=180)即可,注意提前导入timedelta。

可选方案:倒序遍历原地删除

如果因为特殊原因必须原地修改原列表、不能生成新列表,可以采用倒序遍历的写法,删除元素时不会影响未遍历部分的索引:

med_list = gp_clinicals_meds_repeat["GpRepeatMedicationsList"]
cutoff = datetime.now() - relativedelta(months=6)

# 从最后一个元素开始往前遍历
for i in range(len(med_list) - 1, -1, -1):
    entry_date = parser.parse(med_list[i]["Date"])
    if entry_date < cutoff:
        del med_list[i]

gp_clinicals_meds_repeat["TotalItemCount"] = len(med_list)

这个方案不推荐优先使用:当列表长度大、待删除元素多的时候,每次执行del都需要移动列表内存中的后续元素,性能远低于列表推导式的实现,仅适合小数据量的特殊场景。

注意事项
  • 绝对不要在正序遍历列表的过程中增删元素,只要修改了列表长度,就会出现索引偏移问题
  • 涉及月份、年级别的时间差计算,不要硬编码天数近似,优先用dateutil.relativedelta这类成熟的时间工具处理边界情况
  • 你当前的JSON结构自带TotalItemCount字段,过滤完列表后必须同步更新这个值,否则会出现计数和实际数据不匹配的问题

内容的提问来源于stack exchange,提问作者pee2pee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 20:12:19