递归函数返回值未绑定变量时Nonlocal变量未正常更新问题
递归求和函数的结果差异解析
代码与运行结果
def assigned_sum(l: list[int]): res = 0 def recurse(i: int): nonlocal res if i >= len(l): return 0 assigned = recurse(i+1) res += assigned return l[i] recurse(-1) return res def rvalue_sum(l: list[int]): res = 0 def recurse(i: int): nonlocal res if i >= len(l): return 0 res += recurse(i+1) return l[i] recurse(-1) return res test = [1,2,3,4,5] print(f"expected={sum(test)}, lvalue={assigned_sum(test)}, rvalue={rvalue_sum(test)}")
你给出的运行结果为:expected=15, lvalue=15, rvalue=1,但从代码逻辑来看,两个函数的结果本应一致,均为15。出现rvalue=1的结果,大概率是代码存在笔误,下面分别分析两种情况:
一、按你给出的代码逻辑,两个函数的执行流程
1. assigned_sum函数
该函数通过先将递归返回值绑定到局部变量assigned,再累加至res的方式求和:
- 递归调用栈:
recurse(-1)→recurse(0)→recurse(1)→recurse(2)→recurse(3)→recurse(4)→recurse(5)(触发终止条件,返回0) - 回溯阶段:
recurse(4):assigned=0→res +=0(res=0),返回l[4]=5recurse(3):assigned=5→res +=5(res=5),返回l[3]=4recurse(2):assigned=4→res +=4(res=9),返回l[2]=3recurse(1):assigned=3→res +=3(res=12),返回l[1]=2recurse(0):assigned=2→res +=2(res=14),返回l[0]=1recurse(-1):assigned=1→res +=1(res=15),返回l[-1]=5
- 最终res=15,符合预期。
2. rvalue_sum函数
该函数直接将递归返回值累加至res,逻辑上与assigned_sum完全等价:
- 递归调用栈与assigned_sum一致,回溯阶段每次执行
res += recurse(i+1):recurse(4):res +=0(res=0),返回5recurse(3):res +=5(res=5),返回4recurse(2):res +=4(res=9),返回3recurse(1):res +=3(res=12),返回2recurse(0):res +=2(res=14),返回1recurse(-1):res +=1(res=15),返回5
- 最终res=15,与assigned_sum结果一致。
二、若出现rvalue=1的结果,可能的代码错误
如果运行结果中rvalue_sum返回1,最可能的原因是将res += recurse(i+1)误写为res = recurse(i+1),此时代码逻辑变为用递归返回值覆盖res:
- 回溯阶段:
recurse(4):res=0,返回5recurse(3):res=5,返回4recurse(2):res=4,返回3recurse(1):res=3,返回2recurse(0):res=2,返回1recurse(-1):res=1,返回5
- 最终res=1,与你给出的结果一致。这种情况下,res会被每次递归的返回值覆盖,仅保留最后一次赋值的结果(即
recurse(0)的返回值1),而非累加所有递归返回值。
内容的提问来源于stack exchange,提问作者Kevin Jiang
相关产品推荐
相关产品推荐

