python中的浅拷贝和深拷贝
1. 浅拷贝
- 浅拷贝是对于一个对象的顶层拷贝
通俗的理解是:拷贝了引用,并没有拷贝内容。
在ipython3进程验证:
In [1]: a = [11, 22]
In [2]: b = a # 赋值语句相当于一个简单的浅拷贝
In [3]: id(a)
Out[3]: 139773824898824
In [4]: id(b)
Out[4]: 139773824898824
In [5]: import copy
In [6]: c = copy.copy(a) # 进行浅拷贝
In [7]: id(c)
Out[7]: 139773809263624
In [8]: d = [a, c]
In [9]: id(d)
Out[9]: 139773809207944
In [10]: e = copy.copy(d)
In [11]: id(e[0])
Out[11]: 139773824898824
In [12]: id(e[1])
Out[12]: 139773809263624
2. 深拷贝
- 深拷贝是对于一个对象所有层次的拷贝(递归)
在ipython3中验证:
In [1]: import copy
In [2]: a = [11, 22]
In [3]: b = copy.deepcopy(a) # 对a进行深拷贝
In [4]: id(a)
Out[4]: 140025000141512
In [5]: id(b)
Out[5]: 140025000095880
In [6]: a.append(33)
In [7]: a
Out[7]: [11, 22, 33]
In [8]: b
Out[8]: [11, 22]
进一步理解深拷贝:
In [9]: a = [11, 22]
In [10]: b = [33, 44]
In [11]: c = [a, b]
In [12]: d = copy.deepcopy(c)
In [13]: id(a)
Out[13]: 140025000090632
In [14]: id(b)
Out[14]: 140025000091080
In [15]: id(c)
Out[15]: 140025015772744
In [16]: id(d)
Out[16]: 140025015768840
In [17]: id(d[0])
Out[17]: 140025000088136
In [18]: id(d[1])
Out[18]: 140025015702856
In [19]: a.append(66)
In [20]: a
Out[20]: [11, 22, 66]
In [21]: c
Out[21]: [[11, 22, 66], [33, 44]]
In [22]: d
Out[22]: [[11, 22], [33, 44]]
3. 拷贝的其他方式
- 分片表达式可以赋值一个序列
In [23]: a = [11, 22]
In [24]: b = [33, 44]
In [25]: c = [a, b]
In [26]: d = c[:]
In [27]: id(a)
Out[27]: 140025015770376
In [28]: id(b)
Out[28]: 140025000088200
In [29]: id(c)
Out[29]: 140025015698248
In [30]: id(d)
Out[30]: 140025000087624
In [31]: id(d[0])
Out[31]: 140025015770376
In [32]: id(d[1])
Out[32]: 140025000088200
In [33]: a.append(66)
In [34]: a
Out[34]: [11, 22, 66]
In [35]: c
Out[35]: [[11, 22, 66], [33, 44]]
In [36]: d
Out[36]: [[11, 22, 66], [33, 44]]
从上可知分片表达式也是浅拷贝
- 字典的copy方法可以拷贝一个字典
In [38]: d = dict(name="zhangsan", age = 10)
In [39]: co = d.copy()
In [40]: id(d)
Out[40]: 140025000227144
In [41]: id(co)
Out[41]: 140025015714504
In [42]: d
Out[42]: {'name': 'zhangsan', 'age': 10}
In [43]: co
Out[43]: {'name': 'zhangsan', 'age': 10}
In [45]: d = dict(name="zhangsan", ages=[11,22])
In [46]: co = d.copy()
In [48]: d["ages"].append(33)
In [50]: d
Out[50]: {'ages': [11, 22, 33], 'name': 'zhangsan'}
In [51]: co
Out[51]: {'ages': [11, 22, 33], 'name': 'zhangsan'}
4. 注意点
浅拷贝对不可变类型和可变类型的copy不同
- copy.copy对于可变类型,会进行浅拷贝
- copy.copy对于不可变类型,不会拷贝,仅仅是指向
In [88]: a = [11,22,33]
In [89]: b = copy.copy(a)
In [90]: id(a)
Out[90]: 59275144
In [91]: id(b)
Out[91]: 59525600
In [92]: a.append(44)
In [93]: a
Out[93]: [11, 22, 33, 44]
In [94]: b
Out[94]: [11, 22, 33]
In [95]: a = (11,22,33)
In [96]: b = copy.copy(a)
In [97]: id(a)
Out[97]: 58890680
In [98]: id(b)
Out[98]: 58890680
深拷贝对于全部是不可变类型,不会拷贝,仅仅拷贝指向,对于只要其中含有可变类型就会递归拷贝其中的内容。
In [81]: a = (11, 22)
In [82]: b = copy.deepcopy(a)
In [83]: id(a)
Out[83]: 140025015658888
In [84]: id(b)
Out[84]: 140025015658888
In [85]: a = [11, 22]
In [86]: b = (a, 33)
In [87]: c = copy.deepcopy(b)
In [88]: b
Out[88]: ([11, 22], 33)
In [89]: c
Out[89]: ([11, 22], 33)
In [90]: id(b)
Out[90]: 140025000007816
In [91]: id(c)
Out[91]: 140025000005832
In [92]: id(b[0])
Out[92]: 140025000082952
In [94]: id(c[0])
Out[94]: 140025000084168
In [95]:
本文来自博客园,作者:coder-qi,转载请注明原文链接:https://www.cnblogs.com/coder-qi/p/10198704.html