浅拷贝,指的是重新分配一块内存,创建一个新的对象,但里面的元素是原对象中各个子对象的引用。
深拷贝,是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。
浅层与深层复制的区别仅与复合对象(即包含列表或类的实例等其他对象的对象)相关:
- 浅层复制 构造一个新的复合对象,然后(在尽可能的范围内)将原始对象中找到的对象的 引用 插入其中。
- 深层复制 构造一个新的复合对象,然后,递归地将在原始对象里找到的对象的 副本 插入其中。
Python 的赋值语句不复制对象,而是创建目标和对象的绑定关系。直接赋值,无论是可变对象还是不可变对象都不会开辟新的内存空间
id() is == 区别:id() is ==区别-CSDN博客
浅拷贝
浅拷贝,为新变量重新分配一块内存,和原来变量的内存不一样,但浅拷贝完,两个变量中的元素的值是一样的。
切片操作符 :
不能用于字典和集合完成浅拷贝。
浅拷贝是创建一个新对象,该对象的内容是原始对象的引用。换句话说,新对象与原始对象共享内存中的某些部分。当对其中一个对象进行更改时,另一个对象也会受到影响。浅拷贝可以通过切片操作符([:]
)或使用copy
模块中的copy()
函数来实现。
import copy
lst = [[1,2,3], [4,5,6]]
lst2 = lst[1] # lst2的地址和lst[1]的地址相同# 外部地址不同,内部地址相同
print(lst2 is lst[1]) # True
import copy
lst = [[1,2,3], [4,5,6]]
lst2 = copy.copy(lst[1]) # lst2地址不同于lst[1]
print(id(lst[1]) == id(lst2)) # False
# 但是lst[1]中的元素地址相同
print(lst[1][1] is lst2[1]) # True
import copy
tup = (1,2,3)
tup2 = tup[:] # tup2和tup是相同对象
print(tup is tup2) # True
print(id(tup) == id(tup2)) # True
import copy
tup = (1,2,3)
tup2 = copy.copy(tup)
print(tup2 is tup) # True
print(id(tup2) == id(tup)) # True
浅拷贝对不可变的数据类型(无论是内外层),不会开辟新的内存空间
浅拷贝对可变的数据类型外层会开辟新的内存空间,当被拷贝对象的外层数据改变时,不会影响拷贝的对象
浅拷贝对可变的数据类型内层会开辟新的内存空间,当被拷贝对象的内层可变的数据类型改变时,其拷贝对象的内层可变的数据类型也会随之改变
import copy
tup = (1,2,3)
tup2 = copy.copy(tup[1:])
print(tup[1:] is tup2) # False 地址空间不同
print(tup[1:], tup2) # (2, 3) (2, 3)
print(tup[1:] == tup2) # True 值相同
print(tup[2] is tup2[1]) # True 值对应的地址空间相同
深拷贝
Python 中以copy.deepcopy()
来实现对象的深度拷贝
深拷贝会创建一个新对象,并且递归地复制原始对象及其内容,而不仅仅是引用。深拷贝不共享任何内存地址,因此对其中一个对象的更改不会影响另一个对象。
import copy
lst = [1,2,3,4]
lst2 = copy.deepcopy(lst)
print(lst2 == lst) # True
print(lst2 is lst) # False
print(id(lst2) == id(lst)) # False
import copy
tup = (1, 2, 3)
tup_copy = copy.deepcopy(tup)
print(tup == tup_copy) # True
print(tup is tup_copy) # True
print(id(tup) == id(tup_copy)) # True
对于不可变类型(字符串、元组、数值类型),深拷贝和浅拷贝的效果是一样的,因为不可变对象不需要在内存中复制
对于可变类型(列表、字典、集合),深拷贝和浅拷贝的效果是有区别的,主要原因在于可变对象自身的可变性质
总结
不可变类型:赋值、深拷贝、浅拷贝一样。
import copy
tup = (1, 2, 3)
# 下面三个等价
tup_copy = tup
tup_copy = copy.copy(tup)
tup_copy = copy.deepcopy(tup)print(tup == tup_copy) # True
print(tup is tup_copy) # True
print(id(tup) == id(tup_copy)) # True
可变类型:赋值不会开辟新空间,深拷贝和浅拷贝会开辟新空间。
import copy
lst = [1,2,3]
lst2 = lst
# 赋值
print(id(lst) == id(lst2)) # True
print(id(lst[1]) == id(lst2[1])) # True# 浅拷贝
lst3 = copy.copy(lst)
print(id(lst) == id(lst3)) # False 开辟新空间
print(id(lst[1]) == id(lst3[1])) # True 内部元素指向同一地址# 深拷贝
lst4 = copy.deepcopy(lst)
print(id(lst) == id(lst4)) # False
print(id(lst[1]) == id(lst4[1])) # False 内部元素指向不同地址
Python 深拷贝和浅拷贝详解 - JessicaJJmm - 博客园 (cnblogs.com)
[[Python]浅拷贝&深拷贝_python浅拷贝-CSDN博客](https://blog.csdn.net/Letmooning/article/details/141504104?ops_request_misc=&request_id=&biz_id=102&utm_term=python 深拷贝 浅拷贝&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-141504104.142v100pc_search_result_base1&spm=1018.2226.3001.4187)
6、python-详解赋值、浅拷贝、深拷贝_python赋值-CSDN博客
copy — 浅层及深层拷贝操作 — Python 3.13.0 文档