在Python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,Python并没有拷贝这个对象,而只是拷贝了这个对象的引用。
1、浅拷贝:利用切片操作、工厂方法list方法拷贝
2、深拷贝:利用copy中的deepcopy方法进行拷贝
一、浅拷贝
如下,浅拷贝操作:
|
1 2 |
<span style="font-size: 16px;">In [113]: a=[<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">chongyi</span><span style="color: rgba(128, 0, 0, 1);">'</span>,[<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">zhang</span><span style="color: rgba(128, 0, 0, 1);">'</span>,22<span style="color: rgba(0, 0, 0, 1);">]] In [</span>114]: b=a[:]</span> |
b通过切片操作拷贝a
|
1 |
<span style="font-size: 16px;">In [115]: c=list(a)</span> |
c通过工厂方法拷贝a
|
1 2 |
<span style="font-size: 16px;">In [116]: <span style="color: rgba(0, 0, 255, 1);">print</span><span style="color: rgba(0, 0, 0, 1);"> id(a),id(b),id(c) </span>50383040 49098264 50381384</span> |
由上,从a、b、c的id值来看,三者是不同的对象
1、操作1:更改a、b、c第一个元素
|
1 2 3 4 5 6 |
<span style="font-size: 16px;">In [126]: a[0]=<span style="color: rgba(128, 0, 0, 1);">"</span><span style="color: rgba(128, 0, 0, 1);">jiangxi</span><span style="color: rgba(128, 0, 0, 1);">"</span><span style="color: rgba(0, 0, 0, 1);"> In [</span>127]: b[0]=<span style="color: rgba(128, 0, 0, 1);">"</span><span style="color: rgba(128, 0, 0, 1);">shandong</span><span style="color: rgba(128, 0, 0, 1);">"</span><span style="color: rgba(0, 0, 0, 1);"> In [</span>128]: c[0]=<span style="color: rgba(128, 0, 0, 1);">"</span><span style="color: rgba(128, 0, 0, 1);">shanghai</span><span style="color: rgba(128, 0, 0, 1);">"</span><span style="color: rgba(0, 0, 0, 1);"> In [</span>132]: <span style="color: rgba(0, 0, 255, 1);">print</span><span style="color: rgba(0, 0, 0, 1);"> a,b,c [</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">jiangxi</span><span style="color: rgba(128, 0, 0, 1);">'</span>, [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">zhang</span><span style="color: rgba(128, 0, 0, 1);">'</span>, 22]] [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">shandong</span><span style="color: rgba(128, 0, 0, 1);">'</span>, [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">zhang</span><span style="color: rgba(128, 0, 0, 1);">'</span>, 22]] [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">shanghai</span><span style="color: rgba(128, 0, 0, 1);">'</span>, [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">zhang</span><span style="color: rgba(128, 0, 0, 1);">'</span>, 22]]</span> |
结果:各自更改成功,没有异常。
2、操作2:更改b第二个元素里面的第二个元素
|
1 2 3 4 |
<span style="font-size: 16px;">In [137]: b[1][1]=18<span style="color: rgba(0, 0, 0, 1);"> In [</span>138]: <span style="color: rgba(0, 0, 255, 1);">print</span><span style="color: rgba(0, 0, 0, 1);"> a,b,c [</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">jiangxi</span><span style="color: rgba(128, 0, 0, 1);">'</span>, [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">zhang</span><span style="color: rgba(128, 0, 0, 1);">'</span>, 18]] [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">shandong</span><span style="color: rgba(128, 0, 0, 1);">'</span>, [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">zhang</span><span style="color: rgba(128, 0, 0, 1);">'</span>, 18]] [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">shanghai</span><span style="color: rgba(128, 0, 0, 1);">'</span>, [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">zhang</span><span style="color: rgba(128, 0, 0, 1);">'</span>, 18]]</span> |
结果:只是想改b部分,却都发生了改变
3、操作1、操作2解析
针对第一个元素,a、b、c索引不同,更改一个后,其他的不会变,但是对于第二个元素列表[‘zhang’, 22],a、b、c通过不同的索引指向了同一个索引,所以b改完后,其他a、c也都会变。

二、深拷贝
使用copy中的deepcopy方法进行拷贝。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<span style="font-size: 16px;">In [3]: a=[<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">jiangxi</span><span style="color: rgba(128, 0, 0, 1);">'</span>,[<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">chongyi</span><span style="color: rgba(128, 0, 0, 1);">'</span>,123<span style="color: rgba(0, 0, 0, 1);">]] In [</span>4]: <span style="color: rgba(0, 0, 255, 1);">import</span><span style="color: rgba(0, 0, 0, 1);"> copy In [</span>5]: b=<span style="color: rgba(0, 0, 0, 1);">copy.deepcopy(a) In [</span>6]: c=<span style="color: rgba(0, 0, 0, 1);">copy.deepcopy(a) In [</span>7]: b[0]=<span style="color: rgba(128, 0, 0, 1);">"</span><span style="color: rgba(128, 0, 0, 1);">shandong</span><span style="color: rgba(128, 0, 0, 1);">"</span><span style="color: rgba(0, 0, 0, 1);"> In [</span>8]: c[0]=<span style="color: rgba(128, 0, 0, 1);">"</span><span style="color: rgba(128, 0, 0, 1);">shanghai</span><span style="color: rgba(128, 0, 0, 1);">"</span><span style="color: rgba(0, 0, 0, 1);"> In [</span>9]: <span style="color: rgba(0, 0, 255, 1);">print</span><span style="color: rgba(0, 0, 0, 1);"> a,b,c [</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">jiangxi</span><span style="color: rgba(128, 0, 0, 1);">'</span>, [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">chongyi</span><span style="color: rgba(128, 0, 0, 1);">'</span>, 123]] [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">shandong</span><span style="color: rgba(128, 0, 0, 1);">'</span>, [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">chongyi</span><span style="color: rgba(128, 0, 0, 1);">'</span>, 123]] [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">shanghai</span><span style="color: rgba(128, 0, 0, 1);">'</span>, [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">chongyi</span><span style="color: rgba(128, 0, 0, 1);">'</span>, 123<span style="color: rgba(0, 0, 0, 1);">]] In [</span>10]: b[1][0]=<span style="color: rgba(128, 0, 0, 1);">"</span><span style="color: rgba(128, 0, 0, 1);">jinan</span><span style="color: rgba(128, 0, 0, 1);">"</span><span style="color: rgba(0, 0, 0, 1);"> In [</span>11]: <span style="color: rgba(0, 0, 255, 1);">print</span><span style="color: rgba(0, 0, 0, 1);"> a,b,c [</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">jiangxi</span><span style="color: rgba(128, 0, 0, 1);">'</span>, [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">chongyi</span><span style="color: rgba(128, 0, 0, 1);">'</span>, 123]] [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">shandong</span><span style="color: rgba(128, 0, 0, 1);">'</span>, [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">jinan</span><span style="color: rgba(128, 0, 0, 1);">'</span>, 123]] [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">shanghai</span><span style="color: rgba(128, 0, 0, 1);">'</span>, [<span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">chongyi</span><span style="color: rgba(128, 0, 0, 1);">'</span>, 123]]</span> |
由此可见:通过deepcopy的对象引用,互相不影响。
|
1 2 3 4 5 6 7 8 |
<span style="font-size: 16px;">In [12]: [id(x) <span style="color: rgba(0, 0, 255, 1);">for</span> x <span style="color: rgba(0, 0, 255, 1);">in</span><span style="color: rgba(0, 0, 0, 1);"> a] Out[</span>12]: [46257376, 46218488<span style="color: rgba(0, 0, 0, 1);">] In [</span>13]: [id(x) <span style="color: rgba(0, 0, 255, 1);">for</span> x <span style="color: rgba(0, 0, 255, 1);">in</span><span style="color: rgba(0, 0, 0, 1);"> b] Out[</span>13]: [46257184, 46106600<span style="color: rgba(0, 0, 0, 1);">] In [</span>14]: [id(x) <span style="color: rgba(0, 0, 255, 1);">for</span> x <span style="color: rgba(0, 0, 255, 1);">in</span><span style="color: rgba(0, 0, 0, 1);"> c] Out[</span>14]: [46257472, 46248520]</span> |

深拷贝就是在复制某些容器对象(list)的时候,重新在内存里分配一个空间存放复制过来的索引(引用—二层索引),不是重新复制一份底层的对象的内容在内存里。
说白了,深拷贝,复制引用,且单独为其开辟一个内存空间存放。
PS:
1、容器:可以存放其他类型的内容
2、列表(list):可以存放字符串、数值、列表
三、深、浅拷贝总结
思路一:利用切片操作和工厂方法list方法拷贝是浅拷贝,只是拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。
思路二:利用copy中的deepcopy方法进行拷贝是深拷贝,外围和内部元素都进行了拷贝对象本身,而不是引用。
对于数字,字符串和其他原子类型对象等,没有被拷贝的说法(没有层次),即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。