Python中的浅拷贝与深拷贝
2018-03-08 16:59
190 查看
一、浅拷贝
浅拷贝是对于一个对象的顶层拷贝,通俗的理解是:拷贝了引用,并没有拷贝内容。浅拷贝内存图:
例子1:
In [1]: import copy
In [2]: a = [1,2,3]
In [3]: b = [11,22,33]
In [4]: c = [a,b]
In [5]: c
Out[5]: [[1, 2, 3], [11, 22, 33]]
In [6]: d = copy.copy(c)
In [7]: d
Out[7]: [[1, 2, 3], [11, 22, 33]]
In [8]: id(c) # 用来显示a指向的数据内存地址
Out[8]: 1803852506696
In [9]: id(d) # 用来显示b指向的数据内存地址
Out[9]: 1803850684680
In [10]: a.append(4) # 向a列表中添加一个数据
In [11]: d
Out[11]: [[1, 2, 3, 4], [11, 22, 33]] # d是从c拷贝过来的,[a,b]列表指向c。d拷贝来的只是引用,所以数据会发生变化
例子2:In [25]: a = [1,2,3]
In [26]: b = [11,22,33]
In [27]: c = [a,b]
In [28]: d = c[:] # 做切片
In [29]: a[0] = 0 # 修改a列表中的数据
In [30]: c
Out[30]: [[0, 2, 3], [11, 22, 33]]
In [31]: d
Out[31]: [[0, 2, 3], [11, 22, 33]]
In [32]: a.append(4)
In [33]: c
Out[33]: [[0, 2, 3, 4], [11, 22, 33]]
In [34]: d
Out[34]: [[0, 2, 3, 4], [11, 22, 33]] # 因为只是复制了顶层数据,其他的都是对象引用,所以数据会发生改变
因为是浅拷贝,所以只要通过一个引用的修改,那么另外一个变量就能看到的数据变化。
比如:有一个苹果,是小明和小马共有的,如果小马吃了一口苹果,小明的苹果也会少。
二:深拷贝
深拷贝是对于一个对象所有层次的拷贝(递归)。深拷贝内存图:
例子:In [45]: a = [1,2,3]
In [46]: b = [11,22,33]
In [47]: c = [a,b]
In [48]: d = copy.deepcopy(c)
In [49]: id(c) # c列表的内存地址
Out[49]: 1803854612488
In [50]: id(d) # d列表的内存地址
Out[50]: 1803851663432
In [51]: a.append(4) # 向a添加一个数据
In [52]: c
Out[52]: [[1, 2, 3, 4], [11, 22, 33]] # 可以看出原始数据中的a列表被影响了
In [53]: d
Out[53]: [[1, 2, 3], [11, 22, 33]] # 而经过深拷贝的a列表不受影响深拷贝使用deepcopy方法时会通过递归得到方法把整个数据结构全部都拷贝过来了。
比如:小明从冰箱里拿了一个苹果1。小马也想吃苹果,从冰箱里拿了一个和小明一样的苹果2。 初始是一样的,小明吃了一口,小马的苹果没有吃。
注意点:
浅拷贝对不可变类型和可变类型的copy不同
copy.copy对于可变类型(列表、字典),会进行浅拷贝。copy.copy对于不可变类型(元祖、数字、字符串),不会拷贝,仅仅是指向。
In [54]: a = [11,22] In [55]: b = [33,44] In [56]: c = (a,b) # 此时c是元祖 In [57]: d = copy.copy(c) In [58]: id(c) Out[58]: 1803854592584 In [59]: id(d) Out[59]: 1803854592584 In [60]: a.append(33) In [61]: c Out[61]: ([11, 22, 33], [33, 44]) In [62]: d Out[62]: ([11, 22, 33], [33, 44]) In [63]: In [63]: e = copy.deepcopy(c) In [64]: id(c) Out[64]: 1803854592584 In [65]: id(e) Out[65]: 1803853677512 In [66]: a.append(44) In [67]: c Out[67]: ([11, 22, 33, 44], [33, 44]) In [68]: e Out[68]: ([11, 22, 33], [33, 44])如果c是元祖,那么copy时仅仅是copy元祖的引用。
而deepcopy依然是深copy,使用递归copy所有。
总结
基本上只要不是我们自已手动调用的deepcopy方法都是浅拷贝。相关文章推荐
- python的浅拷贝与深拷贝
- python中的深拷贝和浅拷贝理解
- python 中的深拷贝和浅拷贝
- Python复制——浅拷贝、深拷贝、切片
- python中浅谈深浅拷贝
- python开发_copy(浅拷贝|深拷贝)_博主推荐
- python浅复制与深复制 /浅拷贝与深拷贝
- python中的深拷贝与浅拷贝
- [Python]copy模块学习 -- 深拷贝和浅拷贝
- python 赋值 深浅拷贝
- 【python】通过paramiko远程拷贝文件
- Python浅拷贝与深拷贝用法实例
- Python 中的深拷贝和浅拷贝
- 详解python中的浅拷贝和深拷贝
- C++与Python的深浅拷贝比较
- Python 的拷贝
- Python中的深浅拷贝
- python的深拷贝和浅拷贝
- 深度解析:python之浅拷贝与深拷贝