Python中的浅拷贝和深拷贝

本文翻译自copy in Python (Deep Copy and Shallow Copy),讲述了在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()函数返回了一个链表的浅拷贝而deepcopy()函数返回了一个链表的深拷贝。

Python中的浅拷贝和深拷贝
进行深拷贝时会递归地执行对象的拷贝过程。这意味着它首先创建一个新的集合对象,然后递归地使用原始对象中所有子对象的拷贝来填充这个新的集合对象。在深拷贝中,一个对象会被完整地复制到另一个对象中。这意味着发生在新对象中的所有修改都不会影响到原始对象。观察下面的代码:

# 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=" ") 

Output:

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中的浅拷贝和深拷贝

一个浅拷贝意味着创建一个新的集合对象并用原始对象中子对象的引用来填充新对象。拷贝的过程并不是递归的,因此不会创建子对象的拷贝。对于浅拷贝来说,是在另一个对象中创建了对象的引用。这意味着对新对象采取的所有修改也会同时影响原来的对象。比如:

# 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=" ") 

Output:

The original elements before shallow copying
1 2 [3, 5] 4 
The original elements after shallow copying
1 2 [7, 5] 4 

在上例中,在新的链表中的修改使得原始链表也被同时修改了,表明这是一个浅拷贝操作。

注意事项:

浅拷贝和深拷贝之间的区别仅与复合对象有关(指那些本身包含了其他对象的对象,比如链表或者类的实例):

  • 浅拷贝构造一个新的复合对象,然后(尽可能)将对它的引用插入到原始对象中。
  • 深拷贝构造一个新的复合对象,然后递归地将复制对象插入到原始对象中找到的对象中。

以上就是本文的全部内容,如果您喜欢这篇文章,欢迎将它分享给朋友们。

感谢您的阅读,祝您生活愉快!

作者:小美哥
2019-03-17