You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python递归中列表作为函数参数的修改异常问题问询

递归中Python列表的引用问题解析

简化案例的问题分析

你给出的简化代码:

def foo(bar, lst):
  if(bar == 1):
    lst.append(0)
    return
  print(lst)
  foo(1, lst)
  print(lst)
foo(2, [])

输出是:

[]
[0]

核心原因是Python中列表是可变对象,函数参数传递的是对象引用,而非副本。当你调用foo(2, [])时,传入的空列表是内存中的实际对象;进入bar=2的分支后,调用foo(1, lst),这里传递的是同一个列表的引用——两个递归层级操作的是同一个列表对象。

所以当bar=1的分支执行lst.append(0)时,直接修改了内存中的原列表;回到bar=2的分支后,再次打印lst,自然会看到已修改后的[0]。

你尝试的几种操作的区别:

  • lst += [0]和lst.append(0)本质完全一致,都是直接修改原列表对象,因此无法解决问题;
  • lst2 = lst.copy()是创建原列表的新副本,后续对lst2的修改仅作用于新对象,不会影响原列表,因此能得到两个[]的输出。

原排列计数代码的问题解析

再看你提供的原代码,P和P2的核心差异在于N==1的分支:P函数执行了C.append(None),而P2没有。这个差异导致A和A2结果不同,根源还是列表的引用传递:

在P函数的递归逻辑中,上层调用会先执行C.append(e),再调用P(N-1, C),最后执行del C[-1]——原本意图是通过del恢复C的状态,保证下一次循环的正确性。但当N==1时,C.append(None)给列表多添加了一个元素,导致上层的del C[-1]删掉的是这个None,而非之前append的e。这样C无法恢复到添加e之前的状态,后续循环中Temp的计算(基于当前C)会出错,最终导致计数A小于正确值A2。

而P2函数在N==1时没有修改C,上层的del C[-1]能准确删掉之前添加的e,C的状态始终正确,因此A2是正确的排列数。


内容的提问来源于stack exchange,提问作者Richard Wang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 10:27:45