浅谈python的深浅拷贝

时间:2022-09-04 19:49:08

python中有两种数据类型:一种是可变数据类型,一种是不可变数据类型

不可变数据类型包括(整型及其他数据类型,字符串及元组)

可变数据类型(列表,集合,字典,类和类实例)

鉴定是否为拷贝还是只是引用计数加1,我们可以用python的内置函数(id())来验证.

s = "123"
s1 = s
print(id(s),id(s1)) 

浅谈python的深浅拷贝

程序运行结果表明s和s1的内存地址是相同的,所以他们不属于拷贝,只是引用计数加1

下面我们来使用python的内置函数copy试一下看能否真正实现拷贝

s = [[1,2],3,4]
s1 = s.copy()
print(id(s),id(s1))

浅谈python的深浅拷贝

从上面的运行结果来看,好像是拷贝了一份s给s1,但是我们再看一段下面的程序

s = [[1,2],3,4]
s1 = s.copy()
s1[0][1] = 1
s1[1] = 1
print(s,s1)

浅谈python的深浅拷贝

通过运行上面的代码,我们可以看到,如果将原来s1下标为1的数字3改为1,s里面的不变,但是如果改变s1列表中的下标为0的列表元素里面的下标为1的数字,则原来的列表会改变。

为什么的?因为s列表里面的列表元素为可变数据类型,而python内置的函数copy虽然也是拷贝,但是只是拷贝原来变量中的不可变数据类型,可变数据类型只是引用加1,拷贝后和拷贝前变量中的可变数据类型的指针或者内存id是指向同一个地址或内存的。

这就能解释为什么改变拷贝后的变量里面的可变数据类型会导致原来的变量里面的数据改变,我们称这种拷贝为浅拷贝。

既然上面称之为浅拷贝,相对的也就有深拷贝,深拷贝能实现什么呢?能否实现我们认知观念中的那种拷贝形式?看下面代码

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

浅谈python的深浅拷贝

为了能实现深拷贝,我们首先需要引入一个copy模块,从运行结果可以看出来,无论是改变拷贝后的可变数据类型还是不可变数据类型,都不会导致原来变量中的数据改变,以上的方法我们成为深拷贝!