博文参考地址:https://blog.csdn.net/qq_20084101/article/details/82925067

 

最近在撸码的时候发现了一个严重的问题:

a = [1,2]
c = a
a[0] = 3
print(c)

结果:[3,2]
View Code

细心的你,可能已经发现,当我改变的是a[0] 的值时,c的值也跟着改变了

在这里涉及到了一个python的深浅拷贝

1.Phthon中的赋值语句不会创建对象的拷贝,仅仅只是将名称绑定至一个对象,即 a[0] 和 c 是共用一个地址
2.对于不可变对象,通常没有什么差别,即 a = 0
                   b = a
                   a = 1  当 a = 1 时,a 和 b 不在公共同一个地址,a会赋予新地址
3.对于处理可变对象或者可变对象的集合时(数组,字典等),就会出现如上的结果
  但是我们需要的是 修改创建的拷贝时,不改变原始的对象,则需要深拷贝

这是一些概念(浅拷贝:两人共用同一辆奥迪,深拷贝:每一人拥有一模一样的奥迪,一人一辆)

浅拷贝:

浅拷贝意味着构造一个新的集合对象,然后用原始对象中找到的子对象的引用来填充它。
从本质上讲,浅层的复制只有一层的深度。复制过程不会递归,因此不会创建子对象本身的副本。

深拷贝:

深拷贝使复制过程递归。
这意味着首先构造一个新的集合对象,然后递归地用在原始对象中找到的子对象的副本填充它。
以这种方式复制一个对象,遍历整个对象树,以创建原始对象及其所有子对象的完全独立的克隆。

 创建浅拷贝:

list的改变是浅拷贝,因为list只对一层的对象有效,当列表中有子对象,对子对象的修改将影响原始对象和浅拷贝对象

lis = [1,2]
new_lis = list(lis)
lis[0] = 3
print(lis)
print(new_lis)

print("---------------------------")

li = [[1,2],[3,4]]
new_li = list(li)
li[0][0] = 3
print(li)
print(new_li)

结果:
        [[3, 2], [3, 4]]
        [[3, 2], [3, 4]]
---------------------------
         [3, 2]
         [1, 2]
View Code

创建深拷贝:

创建深拷贝的的实质时,创建一个独立的对象,即两个对象完全对立(以上述的车为例)

在Python的标准库中的copy模块可以创建深拷贝,这个模块为创建任意python对象的浅拷贝和深拷贝提供了一个简单接口

1.使用deepcopy()

 

import copy
li = [[1,2],[3,4]]
new_li = copy.deepcopy(li)
li[0][0] = 3
print(li)
print(new_li)

结果:[[3, 2], [3, 4]]
            [[1, 2], [3, 4]]

2.使用 copy.copy() 函数可以创建对象的浅拷贝

 

3.对象可以通过定义特殊的方法 __copy__() 和 __deepcopy__() 来控制如何复制它们。

 

posted on 2018-10-06 12:58  是你啊  阅读(198)  评论(0编辑  收藏  举报