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

Python函数外部列表未更新:按赋值传递为何失效?

问题:LeetCode删除有序数组重复项时外部列表未更新的原因

我在解决LeetCode「删除有序数组中的重复项」问题时,大量测试用例无法通过。本地运行测试代码后发现:调用removeDuplicates()函数时,函数内部的nums被更新,但外部的nums完全没变化。我试过用nums = list(set(nums))替代清空列表再追加元素的操作,依然没用。为什么会这样?Python列表作为参数传递时不是按赋值传递吗?

测试代码

def removeDuplicates(nums):
    nums_ = set(nums)
    nums = []
    for i in nums_:
        nums.append(i)
    print(nums)
    # not working even if I do nums = list(set(nums)) instead of all lines above
    return len(nums)

nums = [1,1,2]
expectedNums = [1,2]

k = removeDuplicates(nums)
if k != len(expectedNums):
    print(False)
for i in range(k):
    if nums[i] != expectedNums[i]:
        print(False)
        print(nums, expectedNums)
        break

运行输出

Output:
False
[1, 1, 2]
[1, 2]


解答

核心原因:Python的参数传递是「按对象引用传递」

你误解了Python的参数传递机制——它不是简单的赋值传递,而是按对象引用传递:

  • 当你把外部的nums传入函数时,函数里的局部变量nums只是拿到了原列表对象的引用,和外部变量指向同一个内存地址。
  • 但如果你在函数里执行nums = []或者nums = list(set(nums)),这相当于给局部变量nums重新绑定了一个新的列表对象,此时它和外部的nums已经指向不同的内存地址了,外部的列表自然不会有任何变化。

另外还要注意:用set处理有序数组会直接打乱元素顺序,而LeetCode的题目要求是在原数组上原地修改,且保持元素的相对顺序,这也是你的解法不符合题目要求的关键问题。

正确的原地修改解法(双指针法)

因为数组是有序的,重复元素必然相邻,用双指针可以高效完成原地去重:

def removeDuplicates(nums):
    if not nums:
        return 0
    # 慢指针i:指向已去重数组的最后一位
    i = 0
    # 快指针j:遍历整个数组寻找新元素
    for j in range(1, len(nums)):
        if nums[j] != nums[i]:
            i += 1
            nums[i] = nums[j]
    # 返回去重后的数组长度
    return i + 1

nums = [1,1,2]
expectedNums = [1,2]

k = removeDuplicates(nums)
if k != len(expectedNums):
    print(False)
else:
    passed = True
    for i in range(k):
        if nums[i] != expectedNums[i]:
            passed = False
            print(f"第{i}位元素不符:{nums[i]} != {expectedNums[i]}")
            break
    print("测试通过" if passed else False)

运行结果

测试通过


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 19:54:52