Python复制–深层复制

时间:2020-02-23 14:42:34  来源:igfitidea点击:

今天,我们将学习Python复制类。
我们还将学习浅拷贝,深拷贝以及为什么我们需要这些不同的拷贝操作。

Python复制

Python库为我们提供了一个Copy类,它具有两个操作– copy(x)和deepcopy(x)—分别用于浅拷贝和深拷贝。
但是为什么我们需要它们?为什么不能使用equals运算符简单地将一个对象分配给另一个对象就足够了?

原因是当我们使用equals python运算符创建新对象时,它实际上创建了对内存中同一对象的引用。
由于两个变量都指向同一个对象,因此一个变量的任何更改也将反映在另一个变量上。
大多数情况下,我们不希望这样做,因此需要单独的复制操作。
让我们通过一个简单的例子来证明关于赋值运算符的理论。

old_list = [1, 2, 3, 4]

new_list = old_list

new_list.append(5)

print("new_list items : ", new_list)
print("old_list items : ", old_list)

上面的python程序的输出是:

new_list items :  [1, 2, 3, 4, 5]
old_list items :  [1, 2, 3, 4, 5]

请注意,我们没有更改old_list,但是由于两个列表都指向同一个对象,因此其中一个的任何更改也会反映在另一个对象上。

同样,如果我们有一个不变的对象,那么赋值运算符就足够了,因为对象值不会改变。

浅拷贝

当我们使用python浅拷贝函数copy()时,它实际上创建了一个新对象,然后插入在原始对象中找到的对象的引用。
因此在上面有整数列表的情况下,浅表复制就足够了,因为列表元素是不可变的。
但是当我们有一个列表列表时,这还不够好。
稍后,我们将研究深度复制,让我们首先来看一下python浅表复制示例。

import copy

old_list = [1, 2, 3, 4]

# python copy - shallow copy
new_list = copy.copy(old_list)

new_list.append(5)

print("new_list items : ", new_list)
print("old_list items : ", old_list)

正如您在上面的输出中看到的那样,由于我们使用复制功能复制列表,因此new_list中的更改并未影响old_list。

现在来看一个示例,其中浅拷贝操作将失败,因为它不会递归地复制原始对象中的元素。

import copy

old_list = [[1, 2], [3, 4]]

new_list = copy.copy(old_list)

new_list[0].append(10)

print("new_list items : ", new_list)
print("old_list items : ", old_list)

上面的python复制示例的输出是:

new_list items :  [[1, 2, 10], [3, 4]]
old_list items :  [[1, 2, 10], [3, 4]]

输出清楚地表明我们需要对对象的深层复制进行单独的操作。

Python深度复制

我们应该对诸如列表列表之类的对象始终使用" deepcopy(x)"功能,以便以递归方式复制对象。
让我们更改上面的浅拷贝示例,并使用深拷贝功能并检查输出。
我还向该程序添加了更多附加和删除操作。

import copy

list_of_list = [[1, 2], [3, 4], ["A", "B"]]

# python deep copy
new_list_of_list = copy.deepcopy(list_of_list)

new_list_of_list[0].append(10)
new_list_of_list[1].remove(3)

list_of_list[2].append("C")

print("list_of_list items : ", list_of_list)
print("new_list_of_list items : ", new_list_of_list)

下图显示了python深度复制操作的输出。

请注意,由于明显的原因,此方法比浅拷贝慢,因此请仅在确实需要时使用。
此外,如果还复制了内部对象,则深层复制将占用更多内存,因此请明智地使用它,并且仅在确实需要时才使用。