python中的浅拷贝,深拷贝的区别和理解

一,python中的可变数据类型和不可变数据类型

1,首先我们知道Python3 中有六个标准的数据类型:
  • Number(数字)
  • String(字符串)
  • List(列表)
  • Tuple(元组)
  • Set(集合)
  • Dictionary(字典)
2,Python3 的六个标准数据类型中可以分为可变数据类型不可变数据类型,具体如下:
  • 不可变数据(3 个): Number(数字)、String(字符串)、Tuple(元组);
  • 可变数据(3 个): List(列表)、Dictionary(字典)、Set(集合)。
3,什么是可变对象,什么是不可变对象:
  • 可变对象: 一个对象在不改变其所指向的地址的前提下,可以修改其所指向的地址中的值;
  • 不可变对象:一个对象所指向的地址上值是不能修改的,如果你修改了这个对象的值,那么它指向的地址就改变了,相当于你把这个对象指向的值复制出来一份,然后做了修改后存到另一个地址上了,但是可变对象就不会做这样的动作,而是直接在对象所指的地址上把值给改变了,而这个对象依然指向这个地址。

二,浅拷贝,深拷贝的区别

1,浅拷贝

对于不可变数据类型: 浅拷贝仅仅是将拷贝生成对象指向被拷贝对象的内存地址id,并未开辟新的内存空间。所以如果修改被拷贝对象的数值,新生成的对象会开辟新的内存空间,数值也不会改变。

对于可变数据类型(主要): 浅拷贝会在最外层开辟新的空间地址,而里面的元素地址还是指向原被拷贝对象。所以如果修改被拷贝对象里面元素的数值,新生成的对象里面元素的数值也会改变;反之亦然。

2,深拷贝

对于不可变数据类型: 和浅拷贝一样,深拷贝仅仅是将拷贝生成对象指向被拷贝对象的内存地址id,并未开辟新的内存空间。修改被拷贝对象的数值,新生成的对象会开辟新的内存空间,数值也不会改变。

对于可变数据类型(主要): 深拷贝本质上是将对象进行递归浅拷贝,被拷贝对象的所有层级中的数据,都会拷贝给新生成的对象,并赋予新的内存地址id,也就是说新生成的对象将完全独立于被拷贝对象。

三,浅拷贝和深拷贝的应用

1,赋值

无论是 “可变数据类型” 还是 “不可变数据类型” ,赋值都是对象的引用。

  • 对于可变数据类型,如果在赋值后,被赋值对象或者赋值对象发生改变,id并没有改变,而对应的赋值对象(被赋值对象)的数据都会同时改变。
    示例如下:
list1 = [1,2,3,4,5]
print(id(list1))

list2 = list1
list1.append(6)

print(id(list1),id(list2))
print(list1,list2)

#------output---------------
140500261430344
140500261430344 140500261430344
[1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6]
  • 对于不可变数据类型,如果在赋值后,被赋值对象或者赋值对象发生改变,该对象都会开辟新的内存地址id。
    示例如下:
strs = "test"
print(id(strs))

str1 = strs
print(id(str1))

strs = strs.upper()
print(id(strs),id(str1))

#------output---------------
140501313245904
140501313245904
140500261499544 140501313245904
2,浅拷贝

1)copy模块

import copy 

temp = ['a', 'b']
a = [1, 2, 3, temp]
b = copy.copy(a)
print(id(a),id(b),id(temp),id(a[3]),id(b[3]))
#------output---------------
140500262299080 140500261881224 140500261477064 140500261477064 140500261477064

2)切片(列表)

temp = ['a', 'b']
a = [1, 2, 3, temp]
b = a[:]
print(id(a),id(b),id(temp),id(a[3]),id(b[3]))
#------output---------------
140500261491464 140500261430600 140500262041800 140500262041800 140500262041800

3)自建copy模块
list:

temp = ['a', 'b']
list1 = [1, 2, 3, temp]
list2 = list1.copy() # 浅拷贝
print(id(list1),id(list2),id(temp),id(list1[3]),id(list2[3]))
#------output---------------
140500261430664 140500676581576 140500261491144 140500261491144 140500261491144

dict:

temp = [7,8,9]
dict1 = {"a":123,"b":456,"c":temp}
dict2 = dict1.copy() 
print(id(dict1),id(dict2),id(temp),id(dict1["c"]),id(dict2["c"]))
#------output---------------
140500261887864 140500261497016 140500261477256 140500261477256 140500261477256
3,深拷贝

copy模块

import copy 

temp = ['a', 'b']
a = [1, 2, 3, temp]
b = copy.deepcopy(a)
print(id(a),id(b),id(temp),id(a[3]),id(b[3]))
#------output---------------
140500262236616 140500261491464 140500261430344 140500261430344 140500261476616

猜你喜欢

转载自blog.csdn.net/TFATS/article/details/108000761