深拷贝与浅拷贝

Posted aiyumo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深拷贝与浅拷贝相关的知识,希望对你有一定的参考价值。

一、单层拷贝

不管深拷贝还是浅拷贝对不可变数据类型都是引用内存地址
不管深拷贝还是浅拷贝对可变数据类型都是会重新创建新的内存空间
赋值是指向同一个对象,内存地址不变
例子:
1、单层浅拷贝:
不可变类型:int、字符串、元组
a = 1 # 不可变类型
copy_a = copy.copy(a) # 单层浅拷贝
print(id(a),id(copy_a)) #内存地址相同
a = [1,2] # 可变类型
copy_a = copy.copy(a) #单层浅拷贝
print(id(a),id(copy_a))#内存地址不相同
 
2、单层深拷贝:
a = 1 # 不可变类型
copy_a = copy.deepcopy(a)
print(id(a),id(copy_a)) #内存地址相同
a = [1,2] # 可变类型
copy_a = copy.deepcopy(a)
print(id(a),id(copy_a))#内存地址不相同
3、赋值:
l1 = [1,2,3,4] 可变类型
l2 = l1
print(id(l1),id(l2)) # 内存地址相同
s1 = ‘a‘ 不可变类型
s2 = s1
print(id(s1),id(s2)) # 内存地址相同
二、嵌套拷贝
总结:
浅拷贝:
外层是不可变类型、不管内层是否可变都是引用拷贝
外层是可变类型,不管内层是否可变都会从新创建新的内存空间
深拷贝:
外层是不可变类型,会递归判断内层数据类型、如果可变则创建新的内存地址、都为不可变就是引用拷贝
外层是可变数据类型、不管内层是否可变都会创新新的内存地址、但是内部如果为可变则递归创建、不可变则为引用地址
浅拷贝:
浅拷贝只做最顶层的数据类型判断
如果顶层是可变类型则创建新的内存空间
如果顶层是不可变数据类型就是引用拷贝
深拷贝:
深拷贝做递归拷贝,可以递归拷贝所有的内部嵌套数据(可以理解为循环遍历做浅拷贝判断)
深拷贝递归拷贝遇到可变类型则创建新的内存空间
深拷贝递归拷贝遇到不可变数据类型就是拷贝的引用
1、浅拷贝嵌套:
# -------------不可变类型----------------
# # 嵌套可变类型
# a = ([1,2],(3,4)) # 不可变数据类型
# copy_a = copy.copy(a)
# print(id(a),id(copy_a)) # 内存地址相同
 
# # 嵌套不可变类型
# a = ((1,2),(3,4)) # 不可变数据类型
# copy_a = copy.copy(a)
# print(id(a),id(copy_a)) # 内存地址相同
 
#-----------可变数据类型------------------------------
# 情况一,内嵌可变数据类型
# a = [(1,2),[3,4]] # 可变数据类型
# copy_a = copy.copy(a)
# print(id(a),id(copy_a)) # 内存地址不相同
# print(id(a[0]),id(copy_a[0])) #内存地址相同
# print(id(a[1]),id(copy_a[1])) #内存地址相同
 
# # 情况二, 可变数据类型 内嵌不可变数据类型
# a = [(1,2),(3,4)]
# copy_a = copy.copy(a)
# print(id(a),id(copy_a)) # 内存地址不相同
2、深拷贝嵌套:
# -------------------不可变数据类型-----------
# # 情况一,内嵌可变类型
# a = ([1,2],(3,4))
# copy_a = copy.deepcopy(a)
# print(id(a),id(copy_a)) # 内存地址不同
# print(id(a[0]),id(copy_a[0])) #内存地址不同
# print(id(a[1]),id(copy_a[1])) #内存地址相同
 
# 情况二,内嵌不可变数据类型
# a = ((1,2),(3,4))
# copy_a = copy.deepcopy(a)
# print(id(a),id(copy_a)) # 内存地址相同
# print(id(a[0]),id(copy_a[0])) #内存地址相同
# print(id(a[1]),id(copy_a[1])) #内存地址相同
 
# -------------------可变数据类型-----------
# 情况一,内嵌可变数据类型
# a = [(1,2),[3,4]]
# copy_a = copy.deepcopy(a)
# print(id(a),id(copy_a)) #内存地址不同
# print(id(a[0]),id(copy_a[0])) # 内存地址相同
# print(id(a[1]),id(copy_a[1])) # 内存地址不同
 
# 情况一, 可变数据类型 内嵌不可变数据类型
# a = [(1,2),(3,4)]
# copy_a = copy.deepcopy(a)
# print(id(a),id(copy_a)) #内存地址不同
# print(id(a[0]),id(copy_a[0])) # 内存地址相同
 

 

以上是关于深拷贝与浅拷贝的主要内容,如果未能解决你的问题,请参考以下文章

深拷贝与浅拷贝的实现(一)

JavaScript深拷贝与浅拷贝

深拷贝与浅拷贝

深拷贝与浅拷贝详解

面试深拷贝与浅拷贝的实现原理

深拷贝与浅拷贝的区别,实现深拷贝的几种方法