如何在字典中处理日期:实现过期优惠券的比较与移除?
优惠券过期检查与移除的正确实现方法
问题描述
我要开发一个小程序,用字典存储优惠券数据(键为商品名称,值为过期日期),核心需求是遍历字典检查并移除过期优惠券(日期早于今日)。
初始优惠券字典:
coupons: dict = {'Rice':'2024-04-03', 'Caviar':'2024-04-05', 'Granola':'2024-08-10', 'Eggs':'2024-04-02'}
遇到的两个问题:
- 最初直接用
datetime(2024,4,4)格式存储日期,虽能正常比较统计过期数量,但执行移除操作时触发TypeError: 'datetime.datetime' object is not iterable错误。 - 改为字符串存储日期后,编写的检查函数运行时触发类型不匹配错误:
def couponCheck(db: dict[str,str]) -> dict: expired: int = 0 now: datetime = datetime.now() for i in db: b = time.strptime(db.get(i),'%Y-%m-%d') if b < now: expired += 1 db.pop(i, None) if expired > 1: print(f'I found {expired} expired coupons in your catalog.') elif expired == 1: print('There was one expired coupon in your catalog.') else: print('I couldn\'t find any expired coupons. Yay!')
错误信息:TypeError: '<' not supported between instances of 'time.struct_time' and 'datetime.datetime'
核心问题分析
- 日期类型不匹配:
time.strptime返回time.struct_time对象,而datetime.now()返回datetime.datetime对象,两类对象无法直接比较。 - 遍历修改冲突:直接遍历字典键的同时执行
pop操作,会改变字典结构,可能引发迭代异常。
修正后的实现代码
from datetime import datetime def couponCheck(db: dict[str, str]) -> dict: expired = 0 # 只保留今日的年月日部分,与存储的日期格式对齐 today = datetime.today().date() # 遍历字典键的副本,避免迭代时修改原字典引发异常 for item in list(db.keys()): # 将字符串日期转为datetime.date对象,统一类型后才能比较 expire_date = datetime.strptime(db[item], '%Y-%m-%d').date() if expire_date < today: expired += 1 db.pop(item) # 根据过期数量输出对应提示 if expired > 1: print(f'I found {expired} expired coupons in your catalog.') elif expired == 1: print('There was one expired coupon in your catalog.') else: print('I couldn\'t find any expired coupons. Yay!') return db # 测试执行 coupons = {'Rice':'2024-04-03', 'Caviar':'2024-04-05', 'Granola':'2024-08-10', 'Eggs':'2024-04-02'} couponCheck(coupons) print(coupons)
关键修正点
- 统一日期类型:使用
datetime.strptime将字符串日期转为datetime.datetime对象,再通过.date()提取日期部分,与today(datetime.date类型)统一,确保可直接比较。 - 安全遍历修改:通过
list(db.keys())创建字典键的副本,遍历副本时修改原字典,避免迭代过程中字典结构变化导致的异常。 - 日期精度对齐:用
datetime.today().date()替代datetime.now(),只保留年月日信息,避免时分秒导致的误判(比如今日凌晨的优惠券不会被误判为过期)。
直接存储datetime对象的解决方案
如果偏好直接用datetime对象存储日期,只需调整遍历方式即可,示例代码:
from datetime import datetime coupons = {'Rice': datetime(2024,4,3), 'Caviar': datetime(2024,4,5), 'Granola': datetime(2024,8,10), 'Eggs': datetime(2024,4,2)} def couponCheck(db: dict[str, datetime]) -> dict: expired = 0 today = datetime.today().date() for item in list(db.keys()): expire_date = db[item].date() if expire_date < today: expired += 1 db.pop(item) # 提示输出逻辑与之前一致 return db
内容的提问来源于stack exchange,提问作者l8r_allocator
相关产品推荐
相关产品推荐

