1:直接赋值,默认浅拷贝传递对象的引用而已,原始列表改变,被赋值的b也会做相同的改变
解析:
这里写图片描述
首先创建一个列表:a=[1,2,3]
然后将a赋值给b: b=a
我们运行一下然后查看他们的地址:
In [19]: a=[1,2,3]
In [20]: id(a)
Out[20]: 140381980736520
In [21]: b=a
In [22]: b
Out[22]: [1, 2, 3]
In [23]: id(b)
Out[23]: 140381980736520
可以看到的是a跟b指向了同一个地址
下面看一下分别对a和b进行操作会产生怎样的结果:
对a进行操作
- 给a添加一个数字:
a.append(4)
In [25]: a
Out[25]: [1, 2, 3]
In [26]: a.append(4)
In [27]: a
Out[27]: [1, 2, 3, 4]
In [28]: id(a)
Out[28]: 140381980736520
In [29]: b
Out[29]: [1, 2, 3, 4]
In [31]: id(b)
Out[31]: 140381980736520
In [32]:
可以看到在对a进行操作的同时由于b指向的地址跟a是一样的,因此b也会添加了一个数字4
对b进行操作
- 给b添加一个数字5:
b.append(5)
In [33]: b
Out[33]: [1, 2, 3, 4]
In [34]: a
Out[34]: [1, 2, 3, 4]
In [35]: b.append(5)
In [36]: b
Out[36]: [1, 2, 3, 4, 5]
In [37]: a
Out[37]: [1, 2, 3, 4, 5]
In [38]: id(a)
Out[38]: 140381980736520
In [39]: id(b)
Out[39]: 140381980736520
同样的b变a也变
这也就说名这种使用a=b的赋值方式只是赋值了一个地地址,一个变化另一个也会跟着变化.因此在实际使用中需要谨慎.
下面看一下不进行添加变量而是重新赋值一个列表会发生什么样的变化
In [41]: b
Out[41]: [1, 2, 3, 4, 5]
In [42]: id(b)
Out[42]: 140381980736520
In [43]: a
Out[43]: [1, 2, 3, 4, 5]
In [44]: id(a)
Out[44]: 140381980736520
In [45]: b=[3,2,1]
In [46]: b
Out[46]: [3, 2, 1]
In [47]: a
Out[47]: [1, 2, 3, 4, 5]
In [48]: id(b)
Out[48]: 140381992083784
In [49]: id(a)
Out[49]: 140381980736520
重新进行赋值以后,b指向的地址就会发生改变,因此对a不会再产生影响.
所以在实际开发中还是要注意这种赋值语句的实际操作是什么样子的.
2 copy浅拷贝,没有拷贝子对象,所以原始数据改变,子对象会改变
解析:
这里写图片描述
首先看一下字典:
In [11]: a={1:[1,2,3]}
In [12]: b=a.copy()
In [13]: b
Out[13]: {1: [1, 2, 3]}
In [14]: a[1].append(4)
In [15]: a
Out[15]: {1: [1, 2, 3, 4]}
In [16]: b
Out[16]: {1: [1, 2, 3, 4]}
In [17]: a[2]=[5]
In [18]: a
Out[18]: {1: [1, 2, 3, 4], 2: [5]}
In [19]: b
Out[19]: {1: [1, 2, 3, 4]}
下面再看一下list
#添加子对象
In [22]: a=[[1,2],[3,4]]
In [23]: a
Out[23]: [[1, 2], [3, 4]]
In [25]: type(a)
Out[25]: list
In [26]: a
Out[26]: [[1, 2], [3, 4]]
In [27]: a[1]
Out[27]: [3, 4]
In [28]: b=a.copy()
In [29]: b
Out[29]: [[1, 2], [3, 4]]
In [30]: a[1].append(6)
In [31]: a
Out[31]: [[1, 2], [3, 4, 6]]
In [32]: b
Out[32]: [[1, 2], [3, 4, 6]]
In [34]: a.append(5)
In [35]: a
Out[35]: [[1, 2], [3, 4, 6], 5]
#添加父对象
In [36]: a.append([5])
In [37]: a
Out[37]: [[1, 2], [3, 4, 6], 5, [5]]
In [38]: b
Out[38]: [[1, 2], [3, 4, 6]]
可以看到的是a子对象发生改变,b也会跟着改变,但是a的父对象发生改变b没有产生变化.同样的b的子对象发生变化a的子对象也会发生变化.
In [40]: a
Out[40]: [[1, 2], [3, 4, 6], 5, [5]]
In [41]: b
Out[41]: [[1, 2], [3, 4, 6]]
In [42]: b[1].append(8)
In [43]: b
Out[43]: [[1, 2], [3, 4, 6, 8]]
In [44]: a
Out[44]: [[1, 2], [3, 4, 6, 8], 5, [5]]
In [45]: b.append([9])
In [46]: b
Out[46]: [[1, 2], [3, 4, 6, 8], [9]]
In [47]: a
Out[47]: [[1, 2], [3, 4, 6, 8], 5, [5]]
深拷贝
深拷贝需要使用copy模块的deepcopy()方法,完全拷贝父对象及其子对象
解析:
这里写图片描述
代码的演示:
In [2]: import copy
In [3]: a=[[1,2],[3,4]]
In [4]: a
Out[4]: [[1, 2], [3, 4]]
In [5]: b=copy.deepcopy(a)
In [6]: b
Out[6]: [[1, 2], [3, 4]]
In [7]: a.append([5])
In [8]: a
Out[8]: [[1, 2], [3, 4], [5]]
In [9]: b
Out[9]: [[1, 2], [3, 4]]
In [10]: a[1].append(5)
In [11]: a
Out[11]: [[1, 2], [3, 4, 5], [5]]
In [12]: b
Out[12]: [[1, 2], [3, 4]]
从代码中也可以看到使用深拷贝后a和b都是独立的对象,互不影响.