Python动态规划记忆化递归返回memo字典出现{...}问题排查
问题根因
输出里的{...}是Python检测到容器存在循环引用时的占位输出——如果字典/列表里存了指向自身的引用,打印时为了避免无限递归展开,就会用这个符号代替。
你的代码有两个核心逻辑错误,直接导致了这个问题:
- 递归返回值不符合设计预期
你给memo存值的逻辑是memo[n] = myfunc(n//2),本意是存n对应的计算结果(整数),但你函数在非终止分支最后执行的是return memo,也就是返回整个memo字典对象,而不是当前n的计算值。
实际执行流程是:- 递归到n=1时,正确返回整数1,所以
memo[2] = 1是符合预期的 - 处理完n=2后,函数返回整个memo字典,于是上层
memo[4]被赋值为memo字典本身 - 同理,memo[8]、memo[16]最终都被赋值为同一个memo字典,形成了字典自我引用的循环,打印时就出现了
{...}
- 递归到n=1时,正确返回整数1,所以
- 可变默认参数隐患
你写的def myfunc(n, memo={})是Python经典易错写法:可变类型的默认参数只会在函数定义时初始化一次,后续多次调用函数会复用同一个字典,容易产生脏数据。
修正方案
递归函数需要单独返回当前n的计算值,不要在递归过程中返回整个memo字典,同时修正可变默认参数的写法:
n = 16 def myfunc(n, memo=None): if memo is None: memo = {} if n in memo: return memo[n] if n == 0: current_res = 0 elif n == 1: current_res = 1 elif n % 2 == 0: current_res = myfunc(n // 2, memo) else: # 原代码奇数分支无处理逻辑,可根据你的实际需求替换 current_res = myfunc(n - 1, memo) memo[n] = current_res return current_res memo_storage = {} myfunc(n, memo_storage) print(memo_storage)
执行上述代码,传入n=16时会输出你预期的结果:{1: 1, 2: 1, 4: 1, 8: 1, 16: 1}
内容的提问来源于stack exchange,提问作者iNeedToAskThis
相关产品推荐
相关产品推荐

