在Python中复制(深拷贝和浅拷贝)
在Python中,赋值语句不会复制对象,它们会在目标和对象之间创建绑定。当我们使用=
运算符时,用户认为这会创建一个新对象;好吧,它没有。它只创建一个共享原始对象引用的新变量。有时用户想要使用可变对象,为了做到这一点,该用户寻找一种方法来创建这些对象的“真实副本”或“克隆”。或者,有时用户想要用户可以修改的副本而不同时自动修改原始副本,为了做到这一点,我们创建对象的副本。
有时需要一份副本,因此可以更改一份副本而不更改另一份。在Python中,有两种方法可以创建副本:
- 深拷贝
- 浅拷贝
为了制作这些副本,我们使用了copy
模块。我们使用copy
模块进行浅拷贝和深拷贝操作。例如
# importing copy module
import copy
# initializing list 1
li1 = [1, 2, [3,5], 4]
# using copy for shallow copy
li2 = copy.copy(li1)
# using deepcopy for deepcopy
li3 = copy.deepcopy(li1)
在上面的代码中, copy()
返回 list 的浅拷贝, deepcopy()
返回 list 的深拷贝。
深拷贝
深拷贝是复制过程递归发生的过程。这意味着首先构造一个新的集合对象,然后递归地用在原始集合中找到的子对象的副本填充它。在深拷贝的情况下,对象的副本被复制到其他对象中。这意味着对对象副本所做的任何更改都不会反映在原始对象中。在Python中,这是使用“ deepcopy() ”函数实现的。
# Python code to demonstrate copy operations
# importing "copy" for copy operations
import copy
# initializing list 1
li1 = [1, 2, [3,5], 4]
# using deepcopy to deep copy
li2 = copy.deepcopy(li1)
# original elements of list
print ("The original elements before deep copying")
for i in range(0,len(li1)):
print (li1[i],end=" ")
print("\r")
# adding and element to new list
li2[2][0] = 7
# Change is reflected in l2
print ("The new list of elements after deep copying ")
for i in range(0,len( li1)):
print (li2[i],end=" ")
print("\r")
# Change is NOT reflected in original list
# as it is a deep copy
print ("The original elements after deep copying")
for i in range(0,len( li1)):
print (li1[i],end=" ")
输出:
The original elements before deep copying
1 2 [3, 5] 4
The new list of elements after deep copying
1 2 [7, 5] 4
The original elements after deep copying
1 2 [3, 5] 4
在上面的示例中,列表中所做的更改对其他列表没有影响,表明该列表是深度复制的。
浅拷贝
浅拷贝意味着构造一个新的集合对象,然后用在原始集合中找到的子对象的引用来填充它。复制过程不会递归,因此不会创建子对象本身的副本。在浅拷贝的情况下,对象的引用被复制到其他对象中。这意味着对对象副本所做的任何更改都会反映在原始对象中。在Python中,这是使用“ copy() ”函数实现的。
# Python code to demonstrate copy operations
# importing "copy" for copy operations
import copy
# initializing list 1
li1 = [1, 2, [3,5], 4]
# using copy to shallow copy
li2 = copy.copy(li1)
# original elements of list
print ("The original elements before shallow copying")
for i in range(0,len(li1)):
print (li1[i],end=" ")
print("\r")
# adding and element to new list
li2[2][0] = 7
# checking if change is reflected
print ("The original elements after shallow copying")
for i in range(0,len( li1)):
print (li1[i],end=" ")
输出:
The original elements before shallow copying
1 2 [3, 5] 4
The original elements after shallow copying
1 2 [7, 5] 4
在上面的示例中,列表中所做的更改确实影响了其他列表,表明该列表是浅拷贝的。
要点:
浅拷贝和深拷贝之间的区别仅与复合对象(包含其他对象的对象,如列表或类实例)相关:
- 浅拷贝构造一个新的复合对象,然后(在可能的范围内)将对原始对象中的对象的引用插入其中。
- 深拷贝构造一个新的复合对象,然后递归地将在原始对象中找到的对象的副本插入其中。