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

为何Python函数未声明全局变量仍修改了原始列表?

为什么你的Python函数会意外修改原始列表?

你踩的这个坑其实是Python里**浅拷贝(shallow copy)**的典型问题,不少刚接触嵌套列表的开发者都会碰到!咱们一步步拆解原因:

问题根源:浅拷贝只复制外层引用

看你函数里的这行代码:

Ab = list(A)

这行是对列表A做了一个浅拷贝。对于普通一维列表来说,浅拷贝确实能生成独立的新列表,但你的A是嵌套列表(列表里装着列表)——浅拷贝只会复制外层列表的结构,里面的每个子列表(比如A[0]、A[1])其实还是和原始列表A共享同一个内存地址的引用。

换句话说,Ab[index]和A[index]指向的是同一个列表对象!所以当你在循环里执行:

Ab[index].append(b[index][0])

你其实是在修改那个共享的子列表,原始列表A里的对应子列表自然也会跟着变化,因为它们根本就是同一个东西。

怎么解决?用深拷贝或手动逐行复制

要让Ab和A完全独立,避免修改原始数据,有两种常用方法:

方法1:使用copy.deepcopy()做深拷贝

深拷贝会递归复制所有嵌套的可变对象,彻底切断和原始列表的关联:

import copy

def make_Ab(A,b):
    n = len(A)
    Ab = copy.deepcopy(A)  # 深拷贝所有层级
    for index in range(n):
        Ab[index].append(b[index][0])
    print(A)  # 现在A不会被修改了
    return Ab

A = [[0.0, 1.0, 1.0, 2.0], [1.0, 3.0, 1.0, 5.0], [2.0, 0.0, 2.0, 4.0]]
b = [[1],[2],[3]]
print(A)
Ab = make_Ab(A,b)
print(A)  # 输出和初始的A完全一致

方法2:手动逐行复制子列表

如果不想导入模块,可以用列表推导式逐个拷贝子列表,这样每个子列表都是独立的新对象:

def make_Ab(A,b):
    n = len(A)
    Ab = [row.copy() for row in A]  # 逐个拷贝内层列表
    for index in range(n):
        Ab[index].append(b[index][0])
    print(A)
    return Ab

A = [[0.0, 1.0, 1.0, 2.0], [1.0, 3.0, 1.0, 5.0], [2.0, 0.0, 2.0, 4.0]]
b = [[1],[2],[3]]
print(A)
Ab = make_Ab(A,b)
print(A)

总结一下

Python里的list(A)、A[:]这类操作都是浅拷贝,只处理外层结构;如果你的数据是嵌套的可变对象(比如列表套列表、字典套列表等),必须用深拷贝或者手动拷贝每一层,才能保证原始数据不被意外修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:12:26