Python列表深复制与浅复制:原理、区别与实战示例

顾星河
顾星河
发布时间:2026-10-14 | 4人浏览过
原创

本文深入解析Python中列表的深复制与浅复制机制。通过代码示例对比直接赋值、切片[:]、copy()及deepcopy()的区别,阐明它们对嵌套对象的处理差异。重点讲解id()函数在追踪内存地址中的应用,帮助开发者理解为何浅复制无法完全隔离嵌套列表,并掌握正确实现数据独立拷贝的方法。

一、深复制与浅复制

列表作为Python内置的核心数据结构,在开发过程中经常涉及数据的拷贝操作。本文将简要探讨列表深复制(Deep Copy)与浅复制(Shallow Copy)的核心概念及实现方式。

首先通过以下代码示例进行观察:


l1 = [5, 4, 3, 2, 1]
# 用两种方法实现对列表l1的拷贝
l2 = l1
l3 = l1[:]
print(l1) # [5, 4, 3, 2, 1]
print(l2) # [5, 4, 3, 2, 1]
print(l3) # [5, 4, 3, 2, 1]
 
#修改l1
l1[0] = 9
print(l1) # [9, 4, 3, 2, 1]
print(l2) # [9, 4, 3, 2, 1]
print(l3) # [5, 4, 3, 2, 1]

执行结果显示,当修改列表l1的第一个元素后,l2的第一个元素随之改变,而l3保持不变。为了探究这一现象背后的内存机制,我们可以利用Python内置函数id()获取各对象的内存地址,进而分析三个列表的实际指向关系:


print(id(l1)) # 2927957162504
print(id(l2)) # 2927957162504
print(id(l3)) # 2927923243528

从输出结果可见,l1与l2的内存地址完全一致,表明二者指向同一块内存区域。执行 l2 = l1 实际上并未创建新对象,而是为l1创建了一个别名(引用)。l2与l1共享同一内存空间,具体关系可通过图示理解:

因此,对l1的任何修改都会直接反映在l2上:

接着分析l3的创建过程。语句 l3 = l1[:] 利用切片操作生成了l1的一个副本,并将其赋值给l3。此时,l3指向新的内存区域,具体逻辑如下:

由于l1与l3指向不同的内存地址,修改l1不会波及l3:

通俗而言,如l2这般,拷贝后的对象与原对象共享同一内存地址,称为浅复制;而如l3这般,系统分配新内存空间并拷贝原始内容,使得拷贝对象与原对象地址不同,称为深复制。

二、复制列表内元素的浅复制

在复制列表整体时,若列表中包含可变对象(如嵌套列表),仅进行浅复制可能无法达到完全隔离的效果。

观察一个具有代表性的案例,代码如下:


l1 = [1,2,3,[1,3]]
l2 = l1[:]
l1[3][1] = 9
print(l1) # [1, 2, 3, [1, 9]]
print(l2) # [1, 2, 3, [1, 9]]

依据前文逻辑,修改l1的元素后,l2似乎不应改变,但实际结果与预期不符。这促使我们深入思考:所谓的“深复制”究竟复制了什么?实际上,列表可视为指向内存区域的指针。l1[3]和l2[3]均为列表元素,执行以下代码验证:


print(id(l2[3])) # 2014816956232
print(id(l1[3])) # 2014816956232

结果显示,l1[3]与l2[3]指向相同的内存地址。这说明在 l2 = l1[:] 操作中,系统仅拷贝了外层列表的引用,而嵌套列表l1[3]的地址被直接复制给了l2[3]。因此,修改l1[3]等同于修改l2[3],导致两者同步变化。这进一步证实列表本质是指针集合。结论明确:列表l2对l1进行了整体复制,但对内部元素执行的是浅复制。

若修改l1[3]内部的具体元素:

三、copy()和deepcopy()

Python的copy模块提供了更完善的对象复制功能。

列举其他几种常见的列表拷贝方式:


l4 = l1 * 1
print(id(l4)) # 2927957916296
l5 = list(l1)
print(id(l5)) # 2927957767816
import copy
l6 = copy.copy(l1)
print(id(l6)) # 2927956854024
l7 = copy.deepcopy(l1)
print(id(l7)) # 2927958503368

观察发现,上述几种方式生成的新对象与原对象的内存地址均不相同,这与字面含义(copy为浅复制,deepcopy为深复制)存在差异。那么,copy()与deepcopy()的本质区别何在?继续通过代码验证:


list1 = [1,2,3,[1,3]]
list2 = list1[:]
list3 = copy.copy(list1)
list4 = copy.deepcopy(list1)
list1[3][0] = 9
print(list1) # [1, 2, 3, [9, 3]]
print(list2) # [1, 2, 3, [9, 3]]
print(list3) # [1, 2, 3, [9, 3]]
print(list4) # [1, 2, 3, [1, 3]]
print(id(list1[3])) # 2927923172616
print(id(list2[3])) # 2927923172616
print(id(list3[3])) # 2927923172616
print(id(list4[3])) # 2927967190728

结果表明,copy()与切片[:]在机制上无本质区别,均对列表内元素执行浅拷贝;而deepcopy()在复制列表内元素时,会递归执行深拷贝,确保嵌套对象也被完整复制。

总结

至此,关于Python列表深复制与浅复制的解析完毕。如需了解更多相关内容,建议查阅本站过往文章或关注后续更新,感谢支持!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表