07-Python-浅拷贝与深拷贝

1. 定义

Python中关于拷贝有两种不同的程度,根据拷贝程度不同划分为:浅拷贝和深拷贝

1. 浅拷贝:只拷贝引用,不拷贝内容

2. 深拷贝:引用和内容都拷贝

2. 赋值

首先说结论:赋值是浅拷贝,只要是x1 = x2的这种形式,不管是什么类型的变量,都是浅拷贝

>>> a = 1
>>> b = a
>>> id(a)
2074664724784
>>> id(b)
2074664724784

可以发现,a和b指向的还是一个空间。被拷贝的只有这个引用即图中的箭头。

浅拷贝下,只要空间中的值1发生变化,则它的引用a和b都会变化

赋值操作就是最简单的浅拷贝,下面讲一下另外一种浅拷贝情况。

3. 浅拷贝

首先说结论,这一种浅拷贝是只复制最外层的列表,内容仍不会复制

>>> import copy
>>> a = [1,2]
>>> b = [3,4]
>>> c = [a,b]
>>> d = copy.copy(c)
>>> id(a)
2074670412224
>>> id(b)
2074670401344
>>> id(c)
2074670401664
>>> id(d)
2074670393152
>>> id(c[0])
2074670412224
>>> id(d[0])
2074670412224
>>> id(c[1])
2074670401344
>>> id(d[1])
2074670401344

可以看出,浅拷贝只是赋值了最外层的列表,具体的内容还是指向同一块空间的

可以再用一个三层嵌套的列表再实验一下

>>> import copy
>>> a = [1,2]
>>> b = [3,4]
>>> c = [5,6]
>>> d = [7,8]
>>> e = [a,b]
>>> f = [c,d]
>>> g = [e,f]
>>> h = copy.copy(g)
>>> id(a)
2220892631360
>>> id(b)
2220892612352
>>> id(c)
2220892620800
>>> id(d)
2220892801728
>>> id(e)
2220892802112
>>> id(f)
2220892801472
>>> id(g)
2220892801792
>>> id(h)
2220892802560
>>> id(g[0])
2220892802112
>>> id(h[0])
2220892802112
>>> id(g[1])
2220892801472
>>> id(h[1])
2220892801472

 4. 深拷贝

深拷贝是引用,内容都进行拷贝,得到的是一个全新的对象

>>> import copy
>>> a = [1,2]
>>> b = copy.deepcopy(a)
>>> id(a)
2157201076480
>>> id(b)
2157200696512
>>> id(a[0])
2157195323696
>>> id(b[0])
2157195323696
>>> id(a[1])
2157195323728
>>> id(b[1])
2157195323728
>>> a[0] = 3
>>> id(a[0])
2157195323760
>>> id(b[0])
2157195323696

 当执行a[0] = 3后:

可以发现,一旦深拷贝后,一个变量的改变是影响不到另一个变量的改变的 

下面再举个例子:

>>> import copy
>>> a = [1,2]
>>> b = [3,4]
>>> c = [a,b]
>>> d = copy.deepcopy(c)
>>> id(c)
2111414536128
>>> id(d)
2111414717120
>>> id(c[0])
2111414546688
>>> id(d[0])
2111414717504
>>> id(c[1])
2111414166720
>>> id(d[1])
2111414536064
>>> id(c[0][0])
2111408793904
>>> id(d[0][0])
2111408793904

5. 拷贝的其它方式

1. 之前学习列表时,相信都遇到过切片的方式,其实切片就是浅拷贝,和copy.copy()的效果一样

>>> import copy
>>> a = [1,2]
>>> b = [3,4]
>>> c = [a,b]
>>> d = c[:]
>>> id(a)
2284222964928
>>> id(b)
2284223226560
>>> id(c)
2284223334208
>>> id(d)
2284223334272
>>> id(c[0])
2284222964928
>>> id(d[0])
2284222964928
>>> id(c[1])
2284223226560
>>> id(d[1])
2284223226560

 2. 字典的拷贝

>>> import copy
>>> a = {"name":"IU","age":18}
>>> b = a.copy()
>>> id(a)
2284222965376
>>> id(b)
2284222965504
>>> a["job"] = "sing song"
>>> a
{'name': 'IU', 'age': 18, 'job': 'sing song'}
>>> b
{'name': 'IU', 'age': 18}
>>> import copy
>>> a = dict(name = "IU",life = [0,100])
>>> b = a.copy()
>>> a
{'name': 'IU', 'life': [0, 100]}
>>> b
{'name': 'IU', 'life': [0, 100]}
>>> a["job"] = "sing song"
>>> a
{'name': 'IU', 'life': [0, 100], 'job': 'sing song'}
>>> b
{'name': 'IU', 'life': [0, 100]}
>>> a["life"].append(50)
>>> a
{'name': 'IU', 'life': [0, 100, 50], 'job': 'sing song'}
>>> b
{'name': 'IU', 'life': [0, 100, 50]}

6. 浅拷贝的注意点

针对copy.copy进行的浅拷贝操作时的注意点

浅拷贝对于可变类型,会进行浅拷贝

>>> a = [1,2]
>>> b = a[:] #等价于b = copy.copy(a)
>>> id(a)
2213222514624
>>> id(b)
2213222442176
>>> a[0] = 3
>>> a
[3, 2]
>>> b
[1, 2]

明确使用copy进行浅拷贝拷贝的是列表的最外层,即便只有一层列表,也会把该层列表拷贝  

浅拷贝对于不可变类型,不会拷贝,仅仅是指向

>>> import copy
>>> a = (1,2,3)
>>> b = copy.copy(a)
>>> id(a)
2340610670272
>>> id(b)
2340610670272

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值