Python
中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的 。本文中重点讲解下Python
中的深浅拷贝知识点
查看内存地址id()
函数
整数在程序中的使用非常广泛,Python为了优化速度,使用了小整数对象池, 避免为整数频繁申请和销毁内存空间。 Python认为其内存是不变的,做了缓存。列表、元组、集合、字典等不会做缓存
数字:-5~256
字符串:“abcd”,出现特殊字符则内存地址不同
v1和v2的内存地址理应不同,但是由于小数据池机制,变得相同;a1和a2同理。 v3和v4:在系统中重新开辟了内存
== :比较值是否相等
is
:判断内存地址是否相同
copy
不管是浅拷贝还是深拷贝,都会开辟新的内存
浅拷贝只拷贝第一层
# 浅拷贝
# 单层列表
V1 = [1, 2, 3, 4]
V2 = copy.copy(V1) # 相当于是开辟新的内存来存储v2
print(id(V1), id(V2)) # 2438370903176 2438359041544
print(V1 == V2) # T
print(V1 is V2) # F 内存地址不同
print(V1[0] is V2[0]) # T
# 嵌套列表
V1 = [1, 2, [3, 4]]
V2 = copy.copy(V1)
print(id(V1), id(V2))
print(id(V1[2]), id(V2[2]))
2438359083336 2438359084168 # 开辟新内存
2438359084104 2438359084104 # 最里层的内存不会变化,只拷贝最外层
deepcopy
拷贝所有的可变类型数据
# 深拷贝
# 单层
V1 = [1, 2, 3, 4]
V2 = copy.deepcopy(V1)
print(id(V1), id(V2)) # 2522354523272 2522354651656 拷贝最外层
print(V1 == V2) # T
print(V1 is V2) # F 内存地址不同
print(V1[0] is V2[0]) # T,里面的123是int型,由于小数据池机制,内存地址相同
# 嵌套
V1 = [1, 2, [3, 4]]
V2 = copy.deepcopy(V1)
print(id(V1), id(V2))
print(id(V1[2]), id(V2[2]))
print(V1 == V2) # T
print(V1 is V2) # F
print(V1[0] is V2[0]) # T 1是不可变类型,小数据池机制,内存相同
print(V1[2] == V2[2]) # T 值相等
print(V1[2] is V2[2]) # F 内存不同
2522354652296 2522354651272 # 所有的可变类型数据都会拷贝,所有最外层和最里层的列表都会拷贝
2522353804168 2522354652616
对于字符串str
、整数型int
、布尔值bool
三种不可变的对象类型,深浅拷贝是一样的,直接在内存中直接开辟空间进行存储。
元组是不可变类型,当里面的元素全部是不可变类型时,深浅拷贝没有区别;只有当里面的元素由可变类型(比如列表时),才会有区别。
import copy
t1 = (1,2,3,4)
t2 = copy.copy(t1)
t3 = copy.deepcopy(t1)
print(id(t1), id(t2))
print(id(t1), id(t3))
2522364792088 2522364792088 # 元组是不可变类型,内存地址相同;深浅拷贝相同
2522364792088 2522364792088
# 元组中嵌套列表(可变元素)
t1 = (1,2,3,[4,5,6])
t2 = copy.copy(t1)
t3 = copy.deepcopy(t1)
print(id(t1), id(t2))
print(id(t1), id(t3))
2522361389368 2522361389368 # 元组是不可变类型,内存地址相同
2522361389368 2522361389928 # 深拷贝情况下不同