python高级之深拷贝和浅拷贝

写在前面的

  • 我们知道python3里面的整数存储是先在内存中找到空间存好数值,然后再把整数的引用传递给变量,同一个整数只分配一次内存,比如:
a = 18
b = 18
id(a)  # 结果为4321867632
id(b)  # 结果为4321867632
  • 变量给变量赋值,实际上就是把变量指向的值的引用赋值给新的变量,比如:
c = [1, 2, 3]
d = [1, 2, 3]
e = c
id(c)  # 结果为4372284616
id(d)  # 结果为4371531592
id(e)  # 结果为4372284616
- 这就是python里面关于变量和引用的关系,如果我们通过列表方法修改e的值,c的值也会跟着改变:
c.append(4) # c和e的结果都是[1, 2, 3, 4]

然后我们从copy模块来说起

copy.copy()

  • 这个方法的作用就是完成浅拷贝
  • 什么是浅拷贝?
    • 通俗的来讲:假如一个变量是列表或者元组字典这种具有多层次结构的类型
    • 浅拷贝就只是改变了最外层的引用值,而里面不管是什么数值,他们的引用都是相同的,比如:
import copy
a1 = [1, 2, 3, 4]
a2 = [7, 8]
b1 = [a1, a2]
b2 = copy.copy(b1)
id(b1) # 结果为:4372285576
id(b2) # 结果为:4372403784
id(b1[0]) # 结果为:4346655304
id(b2[0]) # 结果为:4346655304
a2.append(9) # b1和b2都变成了:[[1, 2, 3, 4], [7, 8, 9]]
- 还有一种特殊情况,如果最外层是元组的话,那么连最外层的引用都不会变:
c1 = (a1, a2)
c2 = copy.copy(c1)
id(c1) # 结果为:4370987208
id(c2) # 结果为:4370987208

copy.deepcopy()

  • 这个就是深拷贝
  • 那么什么具体什么是深拷贝呢?
    • 很简单,同上面来讲就一点区别,就是不光是最外层,连里层所有的数值的引用也全都发生改变了
b3 = copy.deepcopy(b1)
id(b3) # 结果为:4372404936
id(b3[0]) # 结果为:4372424648, 同前面的都不一样,上面的是4346655304
c3 = copy.deepcopy(c1)
id(c3) # 结果为:4371158024,也就是说最外层是元组的话,最外层的引用照样会被改变
- 那么有特殊情况吗?也有,就是内外全部都是不可变类型,比如内外都是元组类型的,那么deepcopy也根本就不拷贝,也就是说由内而外的引用全部不变
d1 = (3, 4, 5)
d2 = (6, 7, 8)
e1 = (d1, d2)
e2 = copy.deepcopy(e1)
id(e1) # 结果为:4370982728
id(e2) # 结果为:4370982728
id(e1[0]) # 4372444720
id(e2[0]) # 4372444720

深拷贝和浅拷贝的区别

  • 深拷贝相当于完全拿一份过来,拷贝源的修改对于它没有任何影响
  • 浅拷贝来说,对于拷贝源通过列表或者字典方法进行修改时,是会受到影响的

其他形式的拷贝

  • 列表的切片相当于浅拷贝:
b4 = b1[:] # 此时b1和b4均为:[[1, 2, 3, 4], [7, 8, 9]]
id(b4) # 4372425352, id(b1)在上面,是4372285576
id(b4[0]) # 4346655304, id(b1[0])在上面,也是4346655304
  • 字典的copy方法相当于浅拷贝:
    • 字典的copy方法,不是copy模块的copy方法
item1 = {"a": 12, "b": 13, "c":14}
item2 = item1.copy()
id(item1) # 4372443928
id(item2) # 4372341456
id(item1["a"]) # 4321867440
id(item2["a"]) # 4321867440
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值