Python 直接赋值、深拷贝、浅拷贝

直接赋值

首先创建一个列表 a , 然后将 a  赋于 b ,此时  ab 均为  [ 11,22 ]

此时 b 存在两种可能,可能 b 直接 复制了一份 a 开辟了一个新的内存空间,或者 b 指向 a 所对应的值

C语言中,是直接开辟新的内存空间,而在python中,b 指向 a 所对应的值

验证如下, a 添加 一个元素 ,查看 b 的值是否改变,结果如下(左边是C语言,右边是python)

id函数可以查看参数变量对应的内存地址,即判断a b 是否真正是同一个值

浅拷贝和深拷贝

使用 copy 模块的深拷贝方法 deepcopy() 拷贝 a c ,此时 a c 地址不一样,说明 深拷贝 直接开辟新空间复制了一份出来 

定义 c 为 【a,b】 将 c 再赋给 d ,此时均为 直接赋值,所以原理如图所示 

继续使用 copy 模块的浅拷贝方法 copy()拷贝 c 给  e

此时,使用浅拷贝会出现两种情况,可能 e 直接 复制了一份 c 开辟了一个新的内存空间,或者 e 指向 c 所对应的值

验证如下,id(c) id(e) 的值不一样,说明开辟了新的空间,拷贝了一份 c

此时,又有两种情况

e 中 指向 a  和 b 所对应的值

e 直接 拷贝 a b 的值,存储在 e

验证,打印 c[0] 地址,和 e[0] 如果是第一种情况,地址相同,第二种情况,地址不同

如图,地址相同,是第一种情况,还是引用指向,添加 a 元素 再次验证,e c 均改变

总结浅拷贝 copy() 方法特征,只拷贝最外层,开辟新空间,里面不变,如果里面是引用指向,并不继续拷贝,照旧

对应的,深拷贝 deepcopy()方法特征,拷贝所有,如果里面是引用指向,也拷贝,验证如下

首先,d 拷贝了c 开辟了新的空间,id(c) id(d) 不同,id(c[0]) id(e[0]) 不同,说明 e 直接 拷贝 a b 的值,存储在 e

再次验证,添加 a 的元素 c 改变,而 e 还是原来的值,没有变

补充:

创建一个元组时,

进行浅拷贝,此时,id(a) id(b) 相同,说明并没有按照正常拷贝,开辟新的空间,仅仅是增加指向,类似直接赋值过程

原理也很好理解,元组创建后不可修改,意义不大

深拷贝同理也是

如果元组内有可变元素,进行浅拷贝时,是指向,进行深拷贝时,开辟新空间进行拷贝

列表切片时是 浅拷贝

字典中的 COPY 方法拷贝一个字典,字典无序,字典中 key是在字典中存放, value只是指向,并不在字典中存放

验证时,添加一个 key:value  value为一个列表,修改 value,打印 d 和 co 发现都改变,说明字典copy中value共享

是浅拷贝

调用函数 C语言中,不会修改实参的值,Python中 参数调用浅拷贝时,会改变,深拷贝时,并不会改变

                    

                                        

使用 浅拷贝 or 深拷贝 取决于具体情况而定

发布了67 篇原创文章 · 获赞 50 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Auuuuuuuu/article/details/94134110