Python如何格式化字典列表Date键并实现近N个月数据过滤
问题解答
两种实现路径都可落地,但从代码可维护性出发,不建议修改现有is_recent函数同时承担过滤和格式化两个职责。is_recent作为判断类函数,只返回布尔值、仅负责时间范围校验的设计更合理,后续调整过滤规则或格式化逻辑时不会互相干扰。
推荐方案:拆分职责实现
保留原有is_recent的判断逻辑不变,单独新增日期格式化函数,在处理流程中先完成过期条目过滤,再对保留的条目做日期格式化:
import pandas as pd from dateutil import relativedelta # 原有过滤函数保持不变 def is_recent(entry, amount): limit_time = pd.Timestamp.today() - relativedelta.relativedelta(months=amount) return pd.to_datetime(entry["Date"]) > limit_time # 新增单独的日期格式化函数 def format_date(entry, date_pattern="%d/%m/%Y"): processed = entry.copy() # %d/%m/%Y 对应要求的d/m/Y(两位日/两位月/四位年)格式 processed["Date"] = pd.to_datetime(processed["Date"]).strftime(date_pattern) return processed # 调用逻辑 allergies_source = session["allergies"] # 第一步:过滤6个月内的条目 recent_entries = [e for e in allergies_source["AllergiesList"] if is_recent(e, 6)] # 第二步:格式化保留条目的日期 session["allergies"] = [format_date(e) for e in recent_entries]
注意:格式化时拷贝原字典是为了避免修改原始数据源的内容,如果不需要保留原始数据可以直接修改原entry。
可选方案:合并逻辑实现(不推荐)
如果一定要把两个操作合并到同一个函数里,不能再把函数放在列表推导的if判断位——判断位仅接收布尔值,无法完成条目修改。需要调整函数返回值,同步修改列表推导的写法:
def process_allergy_entry(entry, month_threshold, date_pattern="%d/%m/%Y"): limit_time = pd.Timestamp.today() - relativedelta.relativedelta(months=month_threshold) entry_dt = pd.to_datetime(entry["Date"]) # 超出时间范围的条目返回None,后续过滤丢弃 if entry_dt <= limit_time: return None # 符合要求的条目格式化日期后返回 processed = entry.copy() processed["Date"] = entry_dt.strftime(date_pattern) return processed # 调用逻辑 allergies_source = session["allergies"] raw_processed = [process_allergy_entry(e, 6) for e in allergies_source["AllergiesList"]] # 过滤掉返回None的过期条目 session["allergies"] = [e for e in raw_processed if e is not None]
这种写法虽然减少了函数数量,但函数职责混杂,后续如果需要单独复用时间过滤逻辑、或者单独复用日期格式化逻辑都很不方便,排查问题时的链路也更长。
内容的提问来源于stack exchange,提问作者pee2pee
相关产品推荐
相关产品推荐

