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

为何list.copy()对二维列表是引用,一维列表是拷贝?附解决方案

为什么list.copy()处理一维列表是独立拷贝,二维列表却会互相影响?

先看你给出的测试代码,运行后确实会发现:修改原二维列表和复制后的二维列表时,两边的元素都会跟着变;但一维列表的修改却各自独立。这个问题的核心,其实是要搞懂Python里浅拷贝和可变/不可变对象的区别,咱们慢慢说:

先搞懂list.copy()的本质

list.copy() 或者常用的切片语法 m[:],实现的都是浅拷贝。简单来说,它只会复制最外层的那个列表容器——对于列表里的元素,它不会重新创建一个新的元素对象,只是复制了元素的引用地址。

一维列表为啥互不影响?

你的一维列表 matrix_1d 里装的都是不可变对象(比如字符串 'I'、'A')。当你执行 matrix2_1d = matrix_1d.copy() 后,新列表里的每个元素都是原字符串的引用。但因为字符串是不可变的,当你做 matrix_1d[0] = 'lol' 时,其实是把原列表第一个位置的引用,从指向原来的 'I' 改成了指向新的字符串 'lol'——而 matrix2_1d 的第一个位置,仍然指向原来的 'I',所以两者的修改不会互相干扰。

二维列表为啥互相影响?

而二维列表 matrix 里的元素是可变对象(也就是另一个列表)。浅拷贝之后,matrix2 里的每个子列表,其实都是原 matrix 里对应子列表的引用——换句话说,matrix[0] 和 matrix2[0] 指向的是同一个列表对象!

所以不管你修改 matrix[0][0] 还是 matrix2[0][1],都是在修改同一个子列表对象本身,自然两边都会看到变化啦。

二维列表的有效复制方案

要让二维列表复制后完全独立,需要实现深拷贝,这里有两种靠谱的方法:

方法1:用copy模块的deepcopy()(通用方案)

这个方法会递归复制所有层级的可变对象,不管你的列表有多少层嵌套都能用:

import copy

# 原二维列表
matrix = [['I','A','O','O','I'],['I','A','O','O','I'],['I','A','O','O','I'],['I','A','O','O','I'],['I','A','O','O','I']]
# 深拷贝
matrix_deep = copy.deepcopy(matrix)

# 修改原列表
matrix[0][0] = 'lol'
# 修改复制后的列表
matrix_deep[0][1] = 'kek'

# 打印验证,两者完全独立
def printMat(m):
    for row in m:
        print(row)

printMat(matrix)
print("---")
printMat(matrix_deep)

方法2:列表推导式+子列表拷贝(针对二维场景更高效)

如果确定你的列表只有两层(二维),可以用列表推导式逐个复制子列表,比deepcopy效率更高:

# 原二维列表
matrix = [['I','A','O','O','I'],['I','A','O','O','I'],['I','A','O','O','I'],['I','A','O','O','I'],['I','A','O','O','I']]
# 逐行拷贝子列表
matrix_deep = [row.copy() for row in matrix]

# 测试修改
matrix[0][0] = 'lol'
matrix_deep[0][1] = 'kek'

# 打印验证
def printMat(m):
    for row in m:
        print(row)

printMat(matrix)
print("---")
printMat(matrix_deep)

用这两种方法复制后的二维列表,修改其中一个就不会影响另一个了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:31:34