为何添加@lru_cache装饰器会破坏组合求和函数?
为什么@functools.lru_cache会破坏组合求和函数?
核心问题出在可变对象的引用缓存上:
- 你的组合函数大概率是用可变的列表(list)逐步构建组合结果,比如递归过程中对同一个列表执行
append和pop的回溯操作。 @lru_cache会缓存函数的返回值,但它缓存的是对象的引用,而非值的副本。当你在后续递归步骤中修改这个列表(比如回溯时pop元素),缓存里的列表引用指向的内存内容也会跟着改变。- 测试用例里出现的重复错误组合
[6,5,4,1,5,3,2],就是因为缓存的列表被后续回溯操作修改,导致之前缓存的结果被污染,最终输出时出现拼接错误的重复内容。
举个简单逻辑:假设函数某次返回列表A,lru_cache存了A的引用。之后函数在另一个分支里修改了A(比如新增元素),缓存里的A也会变成修改后的样子,下次取缓存结果时,拿到的就是被篡改过的错误列表。
移除装饰器后,每次递归调用都会重新计算,不会复用之前的缓存引用,自然不会出现对象被篡改的问题。
内容的提问来源于stack exchange,提问作者A-ar
相关产品推荐
相关产品推荐

