在leetcode问题上遇到了类似的模式.基本上,这两个函数都使用非局部值递归地求和列表a.未分配的值只会在出现时更新res.

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]
f"expected={sum(test)}, lvalue={assigned_sum(test)}, rvalue={rvalue_sum(test)}"

当我被扔进可乐,我得到'expected=15, lvalue=15, rvalue=1'

推荐答案

这两种变体之间的区别可以更清楚地看到:

(a):

res = res + recurse(i+1)

及(b):

res = recurse(i+1) + res

对于您的测试运行,(a)将返回1,而(b)将返回预期的15.

这种差异是由取值res的时刻引起的:递归调用之前或之后.

如果采用递归调用,它将始终为0.这是因为只有在递归中的unwinding才被赋值,而不是在递归中的entering才被赋值.因此,在每个递归级别上发生的所有res的读取,都发生了before任何赋值.然后,当所有的赋值都为res时,它们各自覆盖先前的结果:0 + 5,然后是0 + 4,然后是0 + 3,...直到0 + 1,这是分配给res的最终值.

在正确的版本中,res的值是在递归展开时读取的,所以这意味着我们读取的值是res after,它已经被递归调用更新,所以我们赋值给res:1 + 0,2 + 1,3 + 3,4 + 6,最后5 + 10.

Python相关问答推荐

在Python中对分层父/子列表进行排序

将整组数组拆分为最小值与最大值之和的子数组

Gekko:Spring-Mass系统的参数识别

如何制作10,000年及以后的日期时间对象?

如何从在虚拟Python环境中运行的脚本中运行需要宿主Python环境的Shell脚本?

Asyncio:如何从子进程中读取stdout?

Django—cte给出:QuerySet对象没有属性with_cte''''

我的字符串搜索算法的平均时间复杂度和最坏时间复杂度是多少?

幂集,其中每个元素可以是正或负""""

为什么常规操作不以其就地对应操作为基础?

将链中的矩阵乘法应用于多组值

统计numpy. ndarray中的项目列表出现次数的最快方法

Pandas:将值从一列移动到适当的列

将字节序列解码为Unicode字符串

TypeError:';Locator';对象无法在PlayWriter中使用.first()调用

用由数据帧的相应元素形成的列表的函数来替换列的行中的值

无法在盐流道中获得柱子

我可以同时更改多个图像吗?

根据边界点的属性将图划分为子图

如何通过函数的强式路径动态导入函数?