Python深拷贝与浅拷贝的区别
说说Python中深拷贝与浅拷贝的区别?
答:Python中如果需要拷贝对象,需要使用标准库中的copy模块。而说到copy模块,不得不说的就是深拷贝与浅拷贝。
深拷贝和浅拷贝需要注意的地方就是:可变元素的拷贝
在浅拷贝时,拷贝出来的新对象的地址和原对象是不一样的,但是新对象里面的可变元素(如列表)的地址和原对象里的可变元素的地址是相同的。也就是说浅拷贝它拷贝的是浅层次的数据结构(不可变元素),对象里的可变元素作为深层次的数据结构并没有被拷贝到新地址里面去,而是和原对象里的可变元素指向同一个地址,所以在新对象或原对象里对这个可变元素做修改时,两个对象是同时改变的。但是深拷贝不会这样,这个是浅拷贝相对于深拷贝最根本的区别 。
下面分别来说说这两者的区别:
1、浅拷贝
使用copy模块里面的copy方法实现。
改变原始对象中为可变类型的元素的值,会同时影响拷贝对象;
改变原始对象中为不可变类型的元素的值,不会响拷贝对象。
import copy #定义一个列表,其中第一个元素是可变类型。
list1 = [[1,2], 'fei', 66] #进行浅
list2 = copy.copy(list1) #对象地址是否相同。
print(id(list1))
print(id(list2)) #结果:不同
print(id(list1[0]))#第一个元素地址是否相同。
print(id(list2[0])) #结果:相同
print(id(list1[1]))#第二个元素地址是否相同。
print(id(list2[1])) #结果:相同
list1[0][0] = 2 #改变第一个值,查看复制对象变化。
print(list2)#结果:复制对象发生变化[[2, 2], 'fei', 66]
list1[1] = 'ge'#改变第二个值,查看复制对象变化。
print(list2)#结果:复制对象没发生变化[[2, 2], 'fei', 66]
2、深拷贝
copy模块里面的deepcopy方法实现。
深拷贝,除了顶层拷贝,还对子元素也进行了拷贝。
原始对象和拷贝对象所有的可变元素地址都不一样了。
在python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用
一般有三种方法,
alist=[
1
,
2
,
3
,[
"a"
,
"b"
]]
(1)直接赋值,默认浅拷贝传递对象的引用而已,原始列表改变,被赋值的b也会做相同的改变
alist=[1,2,3,["a","b"]]
b=alist
print (b) #[1, 2, 3, ['a', 'b']]
alist.append(5)
print (alist)#[1, 2, 3, ['a', 'b'], 5]
print (b)#[1, 2, 3, ['a', 'b'], 5]
2)copy浅拷贝,没有拷贝子对象,所以原始数据改变,子对象会改变
alist=[1,2,3,["a","b"]]
import copy
c=copy.copy(alist)
print (alist)
print (c)
alist.append(5)
print (alist)
print (c)
print(alist[3])
alist[3].append('cccc')
print (alist)
print (c)#里面的子对象被改变了
(3)深拷贝,包含对象里面的自对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变
alist=[1,2,3,["a","b"]]
import copy
d=copy.deepcopy(alist)
print (alist)
print(d)
alist.append(5)
print( alist)
print (d)
print(alist[3])
alist[3].append("ccccc")
print (alist)
print(d)
回忆滋润坚持