在本文中,我们将了解如何使用 Python Copy模块来执行深复制和浅复制操作。
现在,深复制和浅复制是什么意思?
让我们通过示例来看一下!
为什么我们需要 Python Copy 模块?
在Python中,一切都用对象来表示。因此,很多情况下,我们可能需要直接复制对象。
在这些情况下,我们不能直接使用赋值运算符。
赋值背后的要点是多个变量可以指向同一个对象。这意味着如果对象使用任何这些变量进行更改,更改将反映在各处!
以下示例使用可变的共享列表对象说明了此问题。
a = [ 1 , 2 , 3 , 4 ] b = a print (a) print (b) b.append( 5 ) # Changes will be reflected in a too! print (a) print (b) |
输出
[1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] |
正如您所看到的,由于两个变量都指向同一个对象,因此当b
发生变化时, 也会发生变化a
!
为了解决这个问题,Python 给我们提供了一种使用Copy模块的方法。
Python复制模块是标准库的一部分,可以使用以下语句导入:
import copy |
现在,在这个模块中,我们主要可以执行两类操作:
- 浅拷贝
- 深拷贝
现在让我们来看看这些方法。
浅拷贝
该方法用于执行浅复制操作。
调用该方法的语法为:
import copy new_obj = copy.copy(old_obj) # Perform a shallow copy |
这会做两件事——
- 创建一个新对象
- 插入在原始对象中找到的对象的所有引用
现在,由于它创建了一个新对象,因此我们可以确定新对象与旧对象不同。
但是,这仍然会保留对嵌套对象的引用。因此,如果我们需要复制的对象有其他可变对象(列表、集合等),这仍然会维护对同一嵌套对象的引用!
为了理解这一点,让我们举个例子。
为了说明第一点,我们将使用一个简单的整数列表来尝试(没有嵌套对象!)
import copy old_list = [ 1 , 2 , 3 ] print (old_list) new_list = copy.copy(old_list) # Let's try changing new_list new_list.append( 4 ) # Changes will not be reflected in the original list, since the objects are different print (old_list) print (new_list) |
输出
[1, 2, 3] [1, 2, 3, 4] [1, 2, 3] |
正如你所看到的,如果我们的对象是一个简单的列表,那么浅复制没有问题。
让我们看另一种情况,我们的对象是列表的列表。
import copy old_list = [[ 1 , 2 ], [ 1 , 2 , 3 ]] print (old_list) new_list = copy.copy(old_list) # Let's try changing a nested object inside the list new_list[ 1 ].append( 4 ) # Changes will be reflected in the original list, since the object contains a nested object print (old_list) print (new_list) |
输出
[[ 1 , 2 ], [ 1 , 2 , 3 ]] [[ 1 , 2 ], [ 1 , 2 , 3 , 4 ]] [[ 1 , 2 ], [ 1 , 2 , 3 , 4 ]] |
在这里,请注意 和 都old_list
受到new_list
了影响!
如果必须避免这种行为,则必须递归复制所有对象以及嵌套对象。
这称为使用 Python 复制模块的深度复制操作。
深拷贝
此方法类似于浅复制方法,但现在将原始对象(包括嵌套对象)中的所有内容复制到新对象中。
要进行深复制操作,我们可以使用以下语法:
import copy new_object = copy.deepcopy(old_object) |
让我们以旧的例子为例,尝试使用深层复制来解决我们的问题。
import copy old_list = [[ 1 , 2 ], [ 1 , 2 , 3 ]] print (old_list) new_list = copy.deepcopy(old_list) # Let's try changing a nested object inside the list new_list[ 1 ].append( 4 ) # Changes will be reflected in the original list, since the objects are different print (old_list) print (new_list) |
输出
[[ 1 , 2 ], [ 1 , 2 , 3 ]] [[ 1 , 2 ], [ 1 , 2 , 3 ]] [[ 1 , 2 ], [ 1 , 2 , 3 , 4 ]] |
请注意,旧列表没有变化。由于所有对象都是递归复制的,所以现在没有问题了!
然而,由于复制所有对象,与浅复制方法相比,这种深复制方法的成本要高一些。
因此,仅在需要时明智地使用它!
结论
在本文中,我们学习了如何使用 Python Copy 模块来执行浅复制和深复制操作。
参考
- Python 复制模块文档
- JournalDev 关于 Python 复制模块的文章