带缓存的Python calc_range函数不符合测试要求,求问题原因
代码问题分析
1. 缓存检查的逻辑与位置错误
- 缓存检查被放在
for循环内部,导致仅当进入循环时才会判断缓存是否存在。当lower == higher时,range(lower, higher)是空序列,循环不会执行,直接走到return cache[lower,higher],此时缓存中无对应键,会抛出KeyError,直接导致测试用例3失败。 - 缓存检查条件
lower and higher in cache.keys()存在语法逻辑错误:该表达式会先判断lower是否为非零值,再判断higher是否单独存在于缓存键中,而非判断(lower, higher)这个元组是否是缓存的键。比如调用calc_range(3,5)时,缓存键是(3,5),higher=5并不在缓存键里,所以条件永远为假,每次调用都会重新生成列表,导致测试用例1中res_1 is res_2断言失败——两次调用返回的是不同的列表对象。
2. 缓存赋值时机错误
原代码在for循环内部的每次append操作后都给缓存赋值,这不仅冗余,还会导致缓存中存储的列表对象在循环过程中被多次覆盖。更严重的是,当lower == higher时,循环不执行,缓存根本不会被赋值,直接触发KeyError。
3. 缓存键的判断方式低效且不必要
使用cache.keys()来判断键是否存在是冗余操作,直接用(lower, higher) in cache即可,既简洁又高效。
修复后的示例代码
cache = dict() def calc_range(lower: int, higher: int) -> list: # 优先检查缓存,存在则直接返回 key = (lower, higher) if key in cache: return cache[key] # 生成结果列表 new_list = list(range(lower, higher)) # 存入缓存 cache[key] = new_list return new_list
该版本先检查缓存,生成列表后一次性存入缓存,可满足所有测试用例要求:
- 测试用例1:两次调用返回同一个列表对象,
res_1 is res_2断言成立 - 测试用例2:缓存中存储的对象与返回的
res_1是同一个,断言成立 - 测试用例3:
lower == higher时生成空列表并存入缓存,两次调用返回同一个空列表,断言成立
内容的提问来源于stack exchange,提问作者Klausi Maus
相关产品推荐
相关产品推荐

