Python双循环删除字典元素时出现KeyError的问题及解决需求
问题:清理字典中1小时内值重复的元素(保留最早项)
需求
删除键为datetime类型、值为字符串类型的字典中,1小时内值相同的重复元素,仅保留最早的一个。
原代码问题
现有代码执行时会触发KeyError——部分符合条件的元素被删除后,外层循环仍会遍历已删除的键,导致访问不存在的键:
#del duplicates within 60min for formatted_key in list(formatted_dict.keys()): for temp_key in list(formatted_dict.keys()): print("formatted_key:", formatted_key) print("temp_key:", temp_key) if(formatted_dict[formatted_key]==formatted_dict[temp_key]): if(temp_key!=formatted_key): td=timedelta(minutes = 60) new_key=formatted_key+td if (new_key>temp_key): del formatted_dict[temp_key] print("key to delet:", temp_key) for key,value in formatted_dict.items(): print(key,value)
错误信息
if(formatted_dict[formatted_key]==formatted_dict[temp_key]): KeyError: datetime.datetime(2022, 10, 25, 8, 16, 12, 286000)
测试数据
2022-10-25 08:14:08.820000 var301533 2022-10-25 08:16:12.286000 var301533 2022-10-25 08:17:05.067000 var003907 2022-10-25 08:19:04.422000 var003907 2022-10-25 08:20:05.021000 var301504 2022-10-25 08:23:04.526000 var301504 2022-10-25 08:23:14.204000 var301504
预期结果
2022-10-25 08:14:08.820000 var301533 2022-10-25 08:17:05.067000 var003907 2022-10-25 08:20:05.021000 var301504
解决方案
核心思路:按时间顺序遍历条目,记录每个值最近保留的时间点,批量删除符合删除条件的键,避免遍历过程中修改字典结构引发异常。
修正后代码
from datetime import datetime, timedelta def clean_duplicates_within_hour(input_dict): # 按时间升序排序字典的键,确保先处理最早的条目 sorted_keys = sorted(input_dict.keys()) # 记录每个值最近一次被保留的时间 value_last_kept = {} keys_to_delete = [] for key in sorted_keys: current_value = input_dict[key] if current_value in value_last_kept: # 计算当前条目与同值已保留条目的时间差 time_diff = key - value_last_kept[current_value] if time_diff <= timedelta(minutes=60): # 时间间隔在1小时内,标记为待删除 keys_to_delete.append(key) else: # 超过1小时,更新该值的最近保留时间 value_last_kept[current_value] = key else: # 首次出现该值,记录其时间 value_last_kept[current_value] = key # 批量删除所有标记的键,避免遍历中修改字典导致的异常 for key in keys_to_delete: del input_dict[key] return input_dict # 构造测试字典(已转为datetime键) formatted_dict = { datetime(2022, 10, 25, 8, 14, 8, 820000): "var301533", datetime(2022, 10, 25, 8, 16, 12, 286000): "var301533", datetime(2022, 10, 25, 8, 17, 5, 67000): "var003907", datetime(2022, 10, 25, 8, 19, 4, 422000): "var003907", datetime(2022, 10, 25, 8, 20, 5, 21000): "var301504", datetime(2022, 10, 25, 8, 23, 4, 526000): "var301504", datetime(2022, 10, 25, 8, 23, 14, 204000): "var301504", } # 执行清理并打印结果 cleaned_dict = clean_duplicates_within_hour(formatted_dict) for key, value in sorted(cleaned_dict.items()): print(f"{key} {value}")
方案说明
- 排序键:先按时间升序排列所有键,确保最早的条目被优先处理并保留。
- 记录保留时间:用
value_last_kept字典跟踪每个值最近一次被保留的时间,避免重复比较。 - 批量删除:先收集所有需要删除的键,最后统一删除,避免遍历字典过程中修改其结构,彻底解决
KeyError问题。 - 准确的时间判断:直接计算当前条目与同值已保留条目的时间差,判断是否在1小时内,逻辑更清晰准确。
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

