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

Python列表拷贝疑问:修改嵌套列表拷贝为何改变原列表?

为什么修改嵌套列表的拷贝会影响原列表?

嘿,这个问题我刚学Python的时候也踩过一模一样的坑!本质上是浅拷贝和深拷贝的区别在搞鬼,咱们一步一步理清楚:

先看两种列表的本质区别

你提到的两种列表看起来都是列表,但内部元素的类型不一样:

  • 第一种是一维列表:a = [1,2,3,4],里面的元素都是整数这种「不可变类型」(int、str、tuple这些都是不可变的)
  • 第二种是嵌套列表:a = [[1,2],[3,4]],里面的元素是另一个列表,属于「可变类型」(list、dict、set这些都是可变的)

浅拷贝的局限性

你大概率是用了list.copy()或者切片a[:]来做拷贝,这些都是浅拷贝操作:

  • 对于一维的不可变元素列表:浅拷贝会创建一个新列表,每个元素是原元素的引用。但因为元素是不可变的,当你修改拷贝里的元素时,其实是把拷贝里的引用换成了新的对象(比如把b[3]从指向4改成指向100),原列表的引用不受影响,所以原列表不会变。
  • 对于嵌套列表:浅拷贝只会拷贝外层列表的结构,里面的子列表只是把引用复制了一份。也就是说,原列表a和拷贝后的列表b里的子列表是同一个对象!比如a[1]和b[1]指向的是内存里的同一个[3,4]列表,你修改b[1][1] = 100,其实是直接修改了这个共享的子列表,原列表自然也跟着变了。

用代码验证一下

你可以试试打印元素的内存地址,就能看明白:

a = [[1,2],[3,4]]
b = a.copy()

# 打印子列表的内存地址,会发现是同一个
print(id(a[1]))  # 比如输出:140703371234560
print(id(b[1]))  # 输出和上面完全一样!

# 修改拷贝的子列表
b[1][1] = 100
print(a)  # 输出 [[1,2],[3,100]],原列表确实变了

怎么解决这个问题?

如果想修改嵌套列表的拷贝但不影响原列表,就得用深拷贝——它会递归地拷贝所有嵌套的可变对象,确保原列表和拷贝列表完全独立:

import copy

a = [[1,2],[3,4]]
b = copy.deepcopy(a)

# 现在子列表的内存地址不一样了
print(id(a[1]))
print(id(b[1]))  # 和上面不同

# 修改拷贝的子列表,原列表不受影响
b[1][1] = 100
print(a)  # 输出 [[1,2],[3,4]]
print(b)  # 输出 [[1,2],[3,100]]

简单总结一下:浅拷贝只拷贝外层结构,嵌套的可变元素还是共享引用;深拷贝会把所有层级的元素都拷贝一遍,彻底断开和原列表的关联。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:31:33