栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【Python】Python中的深浅拷贝

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Python】Python中的深浅拷贝

在Python中其实一切都是对象 甚至连type其本身都是对象 type对象
变量-引用-对象(可变对象 不可变对象)-切片-拷贝(浅拷贝 深拷贝)
比如对a 3来说 首先其值为3 然后告诉Python 它是一个int类型的对象 相当于指向int类型的指针

Python中的可变对象

可以修改的对象 如 list, dict

Python中的不可变对象

不可以修改的对象 如 str, tuple, number 拷贝

深拷贝(deepcopy)

copy模块的deepcopy方法 完全复制了父对象及其子对象

浅拷贝(shallow copy)

copy模块的copy方法 复制父对象 不会复制对象内部的子对象 而是引用子对象的地址 只有一级对象
D { name : zdz , age : 20}
import copy
C1 copy.copy(D)
C2 copy.deepcopy(D)
print(id(C1), id(C2), id(D))
# 2143080833472 2143080875968 2143080833408
print(C1, C2, D)
# { name : zdz , age : 20} { name : zdz , age : 20} { name : zdz , age : 20}
C1[ age ] 22
print(C1)
# { name : zdz , age : 22}
D[ age ] 22
print(D) # { name : zdz , age : 22}
print(C1, C2) # 不变
多级对象
import copy
 name :{ first : james , last : tom },
 age :[12, 13]
C1 copy.copy(D)
C2 copy.deepcopy(D)
D[ age ][0] 14
print(D) # { name : { first : james , last : tom }, age : [14, 13]}
print(C1) # 浅拷贝 { name : { first : james , last : tom }, age : [14, 13]}
print(C2) # 深拷贝 { name : { first : james , last : tom }, age : [12, 13]}
C1[ age ][0] 24
print(D) # { name : { first : james , last : tom }, age : [24, 13]} 
# 可以看到改变浅拷贝之后的字典 源字典也跟着改变了 它们会相互影响
结论 深浅拷贝都创建新的对象 所以id()返回的值不同 浅拷贝的元素使用原始元素的引用或者地址 深拷贝的元素重新拥有新的地址 是一个完全独立的对象。深浅拷贝都占用不同的内存空间如果只有一层顶级对象 那么改变原字典之后 深浅拷贝的字典都不会改变如果有多级对象 那么改变原字典之后 深拷贝的字典不会改变 浅拷贝的字典会改变 切片技术 切片技术用于所有的序列 如字典、列表、元组。 切片不能直接用于字典 只能使用dict.copy()或者dict.deepcopy() 单级列表的切片
L list(range(10))
L1 L[4:]
# L[9] 1000
L1[2] 1000 # 修改拷贝之后的值
print(L) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 源列表不变
L[5] 111 # 修改源列表
print(L1) # [4, 5, 1000, 7, 8, 9] # 拷贝之后的值也不变
多级列表的切片
L1 [8, 9, 10, 11, [1, 2, 3, 4]]
L2 L1[2:]
print(L2) # [10, 11, [1, 2, 3, 4]]
L1[4][0] 0 # 修改源列表的子对象
print(L2) # [10, 11, [0, 1, 2, 3]] L2拷贝的子对象值改变
L1[0] 0 # 修改源列表的父对象(顶级对象)
print(L2) # [10, 11, [0, 1, 2, 3]] L2拷贝的顶级对象值未改变
# 可以得出切片操作其实是一种浅拷贝 对只有一层顶级对象的值来说 修改浅拷贝之后的值源列表都不会变
# 修改多级子对象的值 则浅拷贝之后的值会受影响
# 同理 修改拷贝之后的列表 顶级对象和子对象值 源列表也会作出相应的改变
L2[0] 1000
print(L1) # [0, 9, 10, 11, [0, 2, 3, 4]]
L2[2][0] 111
print(L1) # [0, 9, 10, 11, [111, 2, 3, 4]]
结论 切片实际是一种浅拷贝操作 只拷贝顶级对象数据 子对象则拷贝对象的地址。浅拷贝可以节省内存空间。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/267950.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号