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