天津网站建设方案书,工作期间员工花钱做的网站,ppt模板有哪些网站,个人网站有什么外国广告做I. 简介
深拷贝会递归的创建一个完全独立的对象副本#xff0c;包括所有嵌套的对象#xff0c;而浅拷贝只复制嵌套对象的引用#xff0c;不复制嵌套对象本身。
简单来说就是两者都对原对象进行了复制#xff0c;因此使用is运算符来比较新旧对象时#xff0c;返回的都是F…I. 简介
深拷贝会递归的创建一个完全独立的对象副本包括所有嵌套的对象而浅拷贝只复制嵌套对象的引用不复制嵌套对象本身。
简单来说就是两者都对原对象进行了复制因此使用is运算符来比较新旧对象时返回的都是False(都开辟了新的内存)两者区别在于对嵌套对象有没有进行递归的复制。浅拷贝没有给嵌套对象复制并分配新内存用is来比较嵌套对象时返回的是True而深拷贝对嵌套对象开辟了进行了复制并分配新内存用is来比较嵌套对象时返回的是False。
一个例子如下我们分别对链表的头结点执行深拷贝与浅拷贝
# 原链表 ↓
a1 - b1 - c1 - d1 - e1
# 浅拷贝 ↓ 对于嵌套对象b1, c1, ..., 直接采用了原有引用
a2 - b1 - c1 - d1 - e1
# 深拷贝 ↓ 对于嵌套对象同样开辟了内存空间将其复制
a2 - b2 - c2 - d2 - e2从代码实现来讲深拷贝可以用copy库的deepcopy方法实现浅拷贝除了用copy库的copy方法还有许多其他的实现途径接下来我们将进行介绍。 II. 列表
A. 首先要注意一点对于常用的等号赋值操作这一操作并没有进行任何拷贝只是创建了对现有对象的一个新引用
arr1 [1, 2, 3, 4]
arr2 arr1
print(arr2 is arr1) # True
arr2[0] 0
print(arr1) # [0, 2, 3, 4]B. 对列表进行切片属于浅拷贝操作
arr1 [1, 2, 3, 4]
arr2 arr1[:]
print(arr2 is arr1) # False
arr2[0] 0
print(arr1) # [1, 2, 3, 4]C. 浅拷贝并不会复制嵌套对象
arr1 [1, 2, 3, [4, 5, 6]]
arr2 arr1[:]
print(arr2 is arr1) # False(最外层被复制)
print(arr2[-1] is arr1[-1]) # True(嵌套对象没有被复制)
arr2[-1][0] 0
print(arr1) # [1, 2, 3, [0, 5, 6]](被修改)D. 深拷贝才会复制嵌套对象
import copy
arr1 [1, 2, 3, [4, 5, 6]]
arr2 copy.deepcopy(arr1)
print(arr2 is arr1) # False
print(arr2[-1] is arr1[-1]) # False(嵌套对象也被复制)
arr2[-1][0] 0
print(arr1) # [1, 2, 3, [4, 5, 6]](未修改)E. 使用数据类型本身的构造器仍属于浅拷贝
arr1 [1, 2, 3, [4, 5, 6]]
arr2 list(arr1) # 使用构造器创建新对象, 属于浅拷贝
print(arr2 is arr1) # False
print(arr2[-1] is arr1[-1]) # True
arr2[-1][0] 0
print(arr1) # [1, 2, 3, [0, 5, 6]]F. 对列表进行修改所返回的新列表也属于浅拷贝先浅拷贝再修改
arr1 [1, 2, 3, [4, 5, 6]]
arr2 arr1 [] # 先浅拷贝再修改
print(arr2 is arr1) # False
print(arr2[-1] is arr1[-1]) # True
arr2[-1][0] 0
print(arr1) # [1, 2, 3, [0, 5, 6]]III. 字符串
A. Python中的字符串是不可变对象。因此如果对其进行完整切片[:]可以发现这一过程并没有对字符串本身进行修改。那么Python此时只会直接记录原字符串对象的引用不进行任何拷贝。从设计动机的角度理解既然本身不可修改并且进行的切片操作也没有进行修改那么复制的意义不大所以干脆不进行复制
s1 1234
s2 s1[:]
print(s2 is s1) # True(引用的内容相同)B. 以上结论同样适用于对字符串进行假修改此时也不会进行任何拷贝
s1 1234
s2 s1
print(s2 is s1) # True(没有进行实质修改)C. 想要进行拷贝那就得对字符串进行实质修改。如果切片运算改变了原字符串的内容由于字符串是不可变的因此只能开辟一个新的内存来存储修改后的字符串。此时进行了拷贝过程。注意由于字符串本身没法嵌套对象因此这里不区分深拷贝与浅拷贝
s1 1234
s2 s1[::-1][::-1] # 进行两次修改翻转两次
print(s2 is s1) # False
print(s2) # 1234
s3 s1 5
print(s3 is s1) # FalseD. 使用构造方法str也不会进行任何拷贝只是创建了另一个指向原字符串对象的引用
s1 1234
s2 str(s1)
print(s2 is s1) # TrueE. 使用copy或deepcopy都不能对字符串内容进行拷贝只会新增一个引用
import copy
s1 1234
s2 copy.copy(s1)
s3 copy.deepcopy(s1)
print(s2 is s1) # True
print(s3 is s1) # True