python-深浅拷贝

为什么要有深浅拷贝

在谈谈深浅拷贝之前,先来说一下变量的等号 (=) 赋值,先看一段代码

>>> a=[1,2,3]
>>> b=a
>>> a,b
([1, 2, 3], [1, 2, 3])
>>> a.append(4)
>>> a,b                                 #可以看到修改了a 后,b也跟着改变了
([1, 2, 3, 4], [1, 2, 3, 4])

对于列表这种可变(mutable)数据类型来说,当执行等号赋值后,他们其实都指向内存中的同一个对象,数据是完全共享的,修改其中一个,另一个必将发生改变

但在某些情况下,我们写程序的时候不希望更改一个变量,另一个也跟着改变,不然就乱了套了, 这时就产生了一种需求:

能不能通过某种手段,将对象的数据复制一份,修改其中一个变量时,另一个不会发生改变?

答案是可以的,这时候深浅拷贝就派上用场了


深浅拷贝是什么,区别在哪里

浅拷贝,其实是分为两个词。“ 拷贝 ” 和“ 浅 ”,

  • 拷贝:顾名思义,指的是将对象的数据复制一份
  • 浅:指的是,在复制对象数据的时候,只复制第一层数据

下面来看一段代码

>>> a=[1,[1,2,3],3]
>>> b=a[:]
>>> id(a),id(b)
(61635080, 61645128)  #可以看到a和b的内存地址已经不同了
>>> a.append(4)
>>> a,b
([1, [1, 2, 3], 3, 4], [1, [1, 2, 3], 3]) #可以看到修改a,b并不会发生改变

从上面的代码可以看出,浅拷贝已经能初步解决那个问题了,修改了a, b并不会发生变化

但是浅拷贝只是复制了第一层数据,第二层或者更高层的数据还是共享的,也就是说上面的问题还没有完全解决

浅拷贝只是复制了第一层的数据,当修改其中一个变量的第二层的数据时,另一个也会跟着改变

可以通过下面的代码来验证一下

>>> a[1].append(4)   #通过a[1]来更改了第二层的的数据
>>> a[1],b[1]
([1, 2, 3, 4], [1, 2, 3, 4])  #可以看到修改了其中一个第二层的数据,另一个也会发生改变

这时候深拷贝的作用就出现了,用于祢补浅拷贝的短板,即在复制对象数据的时候,完完整整的复制一份,包括第二层和更高层的数据

深拷贝实现的方式:

>>> import copy
>>> a=[1,[1,2,3],3]
>>> b=copy.deepcopy(a)

而且可以看到修改了其中一个的第二层数据,另一个不会发生改变

>>> a[1].append(4)
>>> a
[1, [1, 2, 3, 4], 3]
>>> b
[1, [1, 2, 3], 3]

深浅拷贝的实现方式

浅拷贝实现的方式有三种

  • 切片操作
  • 工厂函数
  • copy模块中的copy函数

切片操作:

>>> a=[1,[1,2,3],3]
>>> b=a[:]            
>>> a,b
([1, [1, 2, 3], 3], [1, [1, 2, 3], 3])

工厂函数:

>>> a=[1,[1,2,3],3]
>>> b=list(a)            #与等号赋值的区别,就是多了一个list()函数
>>> a,b
([1, [1, 2, 3], 3], [1, [1, 2, 3], 3])

copy模块中的copy函数:

>>> import copy
>>> a=[1,[1,2,3],3]
>>> b=copy.copy(a)
>>> a,b
([1, [1, 2, 3], 3], [1, [1, 2, 3], 3])

深拷贝的实现方式:

>>> import copy
>>> a=[1,[1,2,3],3]
>>> b=copy.deepcopy(a)
>>> a,b
([1, [1, 2, 3], 3], [1, [1, 2, 3], 3])

转载于:https://my.oschina.net/u/3785630/blog/1818495

你可能感兴趣的:(python-深浅拷贝)