python中的深拷贝与浅拷贝

时间:2021-07-19 22:03:48

浅拷贝的时候,修改原来的对象,深拷贝的对象不会发生改变。


对象的赋值


对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用。

aList = ["kel","abc",123]
print(aList, id(aList)) bList = aList bList.append("add") print(aList, id(aList)) print(bList, id(bList))
(['kel', 'abc', 123], 139637569314688)
(['kel', 'abc', 123, 'add'], 139637569314688)
(['kel', 'abc', 123, 'add'], 139637569314688)

同样 numpy 下的数据结构与数据类型的转换(np.array vs. np.asarray)

np.array() 是深拷贝,np.asarray() 是浅拷贝

两者主要的区别在于,array(默认)复制一份对象,asarray不会执行这一动作。

def asarray(a, dtype=None, order=None):
    return array(a, dtype, copy=False, order=order)

示例一

import numpy as np  

arr1=np.ones((3,3))  
arr2=np.array(arr1)  
arr3=np.asarray(arr1)  
print(arr2 is arr1) 
print(arr3 is arr1)
print('arr1:',arr1, id(arr1))  
print('arr2:',arr2, id(arr2)) 
print('arr3:',arr3, id(arr3))  
False
True
('arr1:', array([[ 1., 1., 1.], [ 1., 1., 1.], [ 1., 1., 1.]]), 139637569303856)
('arr2:', array([[ 1., 1., 1.], [ 1., 1., 1.], [ 1., 1., 1.]]), 139637569303776)
('arr3:', array([[ 1., 1., 1.], [ 1., 1., 1.], [ 1., 1., 1.]]), 139637569303856)

示例二

import numpy as np  

arr1=np.ones((3,3))  
arr2=np.array(arr1)  
arr3=np.asarray(arr1)  
arr1[1]=2  
print('arr1:',arr1, id(arr1))  
print('arr2:',arr2, id(arr2)) 
print('arr3:',arr3, id(arr3))  
('arr1:', array([[ 1., 1., 1.], [ 2., 2., 2.], [ 1., 1., 1.]]), 139637569303296)
('arr2:', array([[ 1., 1., 1.], [ 1., 1., 1.], [ 1., 1., 1.]]), 139637569303376)
('arr3:', array([[ 1., 1., 1.], [ 2., 2., 2.], [ 1., 1., 1.]]), 139637569303296)

对象的复制


当你想修改一个对象,而且让原始的对象不受影响的时候,那么就需要使用到对象的复制,对象的复制可以通过三种方法实现:

a、 使用切片操作进行拷贝--slice operation
b、 使用工厂函数进行拷贝,list/dir/set--factoryfunction
c、 copy.copy()--use copymodule

在复制的时候,使用的是浅拷贝,复制了对象,但是对象中的元素,依然使用引用。

person = ["name",["savings",100.00]]
hubby = person[:] #切片操作
wifey = list(person) #使用工厂函数

[id(x) for x in person,hubby,wifey]
print("The person is:", person, id(person))
print("The hubby is:", hubby, id(hubby))
print("The wifey is:", wifey, id(wifey))
('The person is:', ['name', ['savings', 100.0]], 139637569566984)
('The hubby is:', ['name', ['savings', 100.0]], 139637569544848)
('The wifey is:', ['name', ['savings', 100.0]], 139637569405656)
print("The person inside is:", [id(x) for x in person])
print("The hubby inside is:", [id(x) for x in hubby])
print("The wifey inside is:", [id(x) for x in wifey])
('The person inside is:', [139639860076144, 139637569544344])
('The hubby inside is:', [139639860076144, 139637569544344])
('The wifey inside is:', [139639860076144, 139637569544344])

hubby[0] = "kel"
wifey[0] = "jane"
hubby[1][1] = 50.0
print("The person is:", person, id(person))
print("The hubby is:", hubby, id(hubby))
print("The wifey is:", wifey, id(wifey))
('The person is:', ['name', ['savings', 50.0]], 139637570044992)
('The hubby is:', ['kel', ['savings', 50.0]], 139637569460344)
('The wifey is:', ['jane', ['savings', 50.0]], 139637569406160)
print("The person inside is:", [id(x) for x in person])
print("The hubby inside is:", [id(x) for x in hubby])
print("The wifey inside is:", [id(x) for x in wifey])
('The person inside is:', [139639860076144, 139637569810016])
('The hubby inside is:', [139637569356104, 139637569810016])
('The wifey inside is:', [139637569378272, 139637569810016])

在使用浅拷贝的时候,发现引用的id都是相同的,但是字符串的id却发生了变化,是因为在python中,字符串是不可变的,从而在每次进行修改的时候,都是新建一个对象,从而引用发生了变化。


copy模块


浅拷贝和深拷贝的操作都可以在copy模块中找到,其实copy模块中只有两个函数可用,copy()进行浅拷贝操作,而deepcopy()进行深拷贝操作


#1
import copy
aList = [1,"kel",[1,2,3]]
print("The aList is:", aList, id(aList))

shadeList = copy.copy(aList)
print("The shadeList is:", shadeList, id(shadeList))

deepList = copy.deepcopy(aList)
print("The deepList is:", deepList, id(deepList))

aList[2].append("kel")


print("The aList is:", aList, id(aList))

print("The shadeList is:", shadeList, id(shadeList))

print("The deepList is:", deepList, id(deepList))
('The aList is:', [1, 'kel', [1, 2, 3]], 139639722291712)
('The shadeList is:', [1, 'kel', [1, 2, 3]], 139639722170344)
('The deepList is:', [1, 'kel', [1, 2, 3]], 139637569586096)
('The aList is:', [1, 'kel', [1, 2, 3, 'kel']], 139639722291712)
('The shadeList is:', [1, 'kel', [1, 2, 3, 'kel']], 139639722170344)
('The deepList is:', [1, 'kel', [1, 2, 3]], 139637569586096)

#2
import copy
aList = [1,"kel",[1,2,3]]
print("The aList is:", aList, id(aList))

shadeList = copy.copy(aList)
print("The shadeList is:", shadeList, id(shadeList))

deepList = copy.deepcopy(aList)
print("The deepList is:", deepList, id(deepList))

shadeList[2].append("kel")


print("The aList is:", aList, id(aList))

print("The shadeList is:", shadeList, id(shadeList))

print("The deepList is:", deepList, id(deepList))
('The aList is:', [1, 'kel', [1, 2, 3]], 139637569846448)
('The shadeList is:', [1, 'kel', [1, 2, 3]], 139637569406520)
('The deepList is:', [1, 'kel', [1, 2, 3]], 139637569407240)
('The aList is:', [1, 'kel', [1, 2, 3, 'kel']], 139637569846448)
('The shadeList is:', [1, 'kel', [1, 2, 3, 'kel']], 139637569406520)
('The deepList is:', [1, 'kel', [1, 2, 3]], 139637569407240)

#3
import copy
aList = [1,"kel",[1,2,3]]
print("The aList is:", aList, id(aList))

shadeList = copy.copy(aList)
print("The shadeList is:", shadeList, id(shadeList))

deepList = copy.deepcopy(aList)
print("The deepList is:", deepList, id(deepList))

deepList[2].append("kel")
print("The deepList is:", deepList, id(deepList))

print("The aList is:", aList, id(aList))

print("The shadeList is:", shadeList, id(shadeList))
('The aList is:', [1, 'kel', [1, 2, 3]], 139637569460776)
('The shadeList is:', [1, 'kel', [1, 2, 3]], 139637569461496)
('The deepList is:', [1, 'kel', [1, 2, 3]], 139637569585592)
('The deepList is:', [1, 'kel', [1, 2, 3, 'kel']], 139637569585592)
('The aList is:', [1, 'kel', [1, 2, 3]], 139637569460776)
('The shadeList is:', [1, 'kel', [1, 2, 3]], 139637569461496)

参考文献


numpy 下的数据结构与数据类型的转换(np.array vs. np.asarray)

numpy中array和asarray的区别

python中的深拷贝与浅拷贝