07-深浅拷贝--就问你前面的知识掌握了没?
一。拷贝
what:计算机Ctrl+C 和 Ctrl+V了解一下。
二。浅拷贝:当然和直接复制粘贴不一样,不要会错意。
2.1引入:
机智的我发现通过copy()方法得到的新列表list2的id与list1的不同。
>>> list1 = [[111,222],333,444] >>> list2 = list1.copy() >>> print(id(list1),id(list2)) 20538600 20539976
没错,同样机智的我发现虽然列表的内存地址不同,但是列表中元素的内存地址是相同的。看到这,为我的机智点个赞^_^
>>> id(list1[0]),id(list2[0]) (20538056, 20538056) >>> id(list1[1]),id(list2[1]) (3620752, 3620752) >>> id(list1[2]),id(list2[2]) (20909840, 20909840)
没错,又是那个机智的我,画了一张图,关于copy()方法的。。。。
不晓得屏幕面前的你,看完这张图能否理解以下代码底层发生的过程呢?
# 第一种
>>> list1 = [[111,222],333,444] >>> list2 = list1.copy() >>> list2[-1] = 555 >>> print(list1,list2) [[111, 222], 333, 444] [[111, 222], 333, 555]
and下面这个
# 第二种
>>> list1 = [[111,222],333,444] >>> list2 = list1.copy() >>> list2[0][0] = 0 >>> print(list1,list2) [[0, 222], 333, 444] [[0, 222], 333, 444]
如果看不懂的话,请自行去找矮跟,枪毙1000次,然后回来思考一下人生,看我分析一遍(这才是重点!!!(^-^)V)
需要储备的知识:可变类型和不可变类型在内存中的底层原理
第一种:修改list2中的444,因为444是整型,属于不可变类型,会在内存空间开辟一块新的地址来存555,修改前的444还是原来的地址,与list1绑定。
第二种:修改的是list2中的小列表的元素,而列表属于可变类型,只有列表中元素的id会发生变化,但是小列表的内存地址不会发生变化,list1和list2同时指向改变了元素的列表地址。
总结:(没错,我就是这么贴心!)
语法:例list2 = list1.copy()
浅拷贝是针对只读操作,它是把原列表的第一层内存地址不加区分(可变类型和不可变类型)的完全拷贝给新列表,对于不可变类型的赋值就是产生了新的值,对原列表不产生任何影响。但是对于可变类型,可以改变可变类型中包含的值,于是原列表也会受到影响。就是不管哪个列表中的可变类型发生变化,都会影响两个列表。
三。深拷贝
为啥叫深拷贝:笨,因为上面那个家伙叫浅拷贝。。。。。
引入:机智的你会发现修改list2,list1不会发生变化。。。
import copy list1 = [[111,222], 333,444] list2 = copy.deepcopy(list1) print(id(list1),id(list2)) print(id(list1[1])) print(id(list2[1])) list2[0][1] = 4 print(list1) print(list2)
那么参照浅拷贝的分析步骤聪明的你应该能分析出是哪里的问题了吗?
总结第二弹:
深拷贝与浅拷贝的区别:深拷贝对不可变类型与可变类型进行了区分,深拷贝可以针对改操作哦
四、表扬自己,画了好几张图。。。。。。。(^-^)V