如何移除字典内日期列表中30天内的重复项并保留最后一项?
解决日期字典的30天间隔去重(保留原列表最后出现项)
核心需求
对字典中每个键对应的日期列表,将所有间隔30天内的日期归为一组,每组仅保留原列表中最后出现的日期;需支持跨月的30天内日期处理,且算法高效。
高效实现思路
- 绑定原索引:给每个日期标记其在原列表中的位置,用于判断哪个是最后出现的项。
- 日期排序与贪心分组:将日期按时间升序排序,从最早日期开始,把所有30天内的日期归为一组,每组保留原索引最大的项(即原列表最后出现的日期)。
- 恢复原顺序:将最终保留的日期按其在原列表中的出现顺序排序,保证输出格式符合预期。
Python代码实现
from datetime import datetime, timedelta def process_dates(date_list): # 为每个日期绑定:datetime对象、原列表索引、原日期字符串 dated_items = [ (datetime.strptime(date, '%Y-%m-%d'), idx, date) for idx, date in enumerate(date_list) ] if not dated_items: return [] # 按日期升序排序,便于贪心分组 dated_items.sort(key=lambda x: x[0]) result = [] current_start_dt, current_max_idx, current_max_date = dated_items[0] for dt, idx, date_str in dated_items[1:]: # 判断当前日期是否在当前组的30天窗口内 if dt - current_start_dt <= timedelta(days=30): # 保留原列表中最后出现的项(索引更大的) if idx > current_max_idx: current_max_idx = idx current_max_date = date_str else: # 超出窗口,将当前组的结果加入列表,开启新组 result.append(current_max_date) current_start_dt = dt current_max_idx = idx current_max_date = date_str # 加入最后一组的结果 result.append(current_max_date) # 按原列表中的出现顺序排序结果 result.sort(key=lambda x: date_list.index(x)) return result # 测试示例字典 original_dict = { 'a': ['2020-12-11'], 'b': ['2020-05-30', '2022-09-11'], 'c': ['2021-07-28', '2022-07-20', '2022-07-07'], 'd': ['2022-04-17', '2022-04-18', '2022-04-15', '2022-08-20'] } processed_dict = {key: process_dates(dates) for key, dates in original_dict.items()} # 输出处理结果 for key, dates in processed_dict.items(): print(f"{key} : {dates}")
代码说明
- 跨月场景支持:通过
datetime对象计算时间差,直接判断是否在30天内,不受月份边界限制,比如['2022-03-01', '2022-02-16']会被正确识别为30天内的组。 - 效率优化:核心逻辑基于排序(O(n log n))和一次遍历(O(n)),远优于暴力两两对比的O(n²)算法,适合处理大规模日期列表。
- 结果顺序匹配:最后通过原列表索引排序,保证输出的日期顺序和原列表中保留项的出现顺序一致,符合示例要求。
运行结果
a : ['2020-12-11'] b : ['2020-05-30', '2022-09-11'] c : ['2021-07-28', '2022-07-07'] d : ['2022-04-15', '2022-08-20']
内容的提问来源于stack exchange,提问作者ImNotSureAboutStats
相关产品推荐
相关产品推荐

