1. 什么是copy和deepcopy
在Python编程中,有时候需要需要在程序中创建一个新的副本来修改或操作。当涉及到复杂的数据类型,如列表、字典和类等时,就需要使用copy()和deepcopy()函数来创建新的副本了。
1.1 copy()
copy()函数是Python中列表、字典等可变数据类型的默认浅复制方式,即创建一个新的副本,但副本只复制了父对象中的引用,而不复制从父对象中所有子对象。
下面的代码演示了使用.copy()函数复制一个列表:
list1 = [1, 2, [3, 4]]
list2 = list1.copy()
print("list1: ", list1)
print("list2: ", list2)
此输出为:
list1: [1, 2, [3, 4]]
list2: [1, 2, [3, 4]]
由此可以看到,list1和list2是两个不同的列表,但是它们之间的子对象依然是一致的。如果在list2中修改子对象,那么list1也会受到影响,因为这些子对象只是单纯的引用,而不是复制品。
1.2 deepcopy()
deepcopy()函数则是创建一个全新的副本,即复制所有的父对象以及它们子对象。
下面的代码演示了使用copy.deepcopy()函数复制一个嵌套列表中的所有对象:
import copy
list1 = [1, 2, [3, 4]]
list2 = copy.deepcopy(list1)
print("list1: ", list1)
print("list2: ", list2)
此输出为:
list1: [1, 2, [3, 4]]
list2: [1, 2, [3, 4]]
由此可以看到,list1和list2是两个不同的列表,而且它们之间的子对象也是完全不同的,所以修改一个列表不会对另一个列表造成任何影响。
2. copy()和deepcopy()的用例
2.1 使用copy()复制列表
下面的代码演示了如何使用.copy()函数来浅拷贝一个列表:
list1 = [1, 2, [3, 4]]
list2 = list1.copy()
list2[2][0] = 5
print("list1: ", list1)
print("list2: ", list2)
此输出为:
list1: [1, 2, [5, 4]]
list2: [1, 2, [5, 4]]
由于list2只是复制了list1的引用,所以当我们修改list2中的子对象时,list1也会发生相同的更改。这种不希望发生的情况可能导致程序出现错误。
2.2 使用deepcopy()复制嵌套列表
下面的代码演示了如何使用copy.deepcopy()函数来深拷贝一个列表:
import copy
list1 = [1, 2, [3, 4]]
list2 = copy.deepcopy(list1)
list2[2][0] = 5
print("list1: ", list1)
print("list2: ", list2)
此输出为:
list1: [1, 2, [3, 4]]
list2: [1, 2, [5, 4]]
由于使用了深拷贝,所以当我们修改list2中的子对象时,list1并不会受到影响。
2.3 使用copy()复制字典
下面的代码演示了如何使用.copy()函数来浅拷贝一个字典:
dict1 = {'a': 1, 'b': [1, 2]}
dict2 = dict1.copy()
dict2['b'][0] = 3
print("dict1: ", dict1)
print("dict2: ", dict2)
此输出为:
dict1: {'a': 1, 'b': [3, 2]}
dict2: {'a': 1, 'b': [3, 2]}
同样,当我们修改dict2中的子对象时,dict1也会发生相同的更改,因为它们只是引用同一组对象,而没有复制新的对象。
2.4 使用deepcopy()复制嵌套字典
下面的代码演示了如何使用copy.deepcopy()函数来深拷贝一个字典:
import copy
dict1 = {'a': 1, 'b': [1, 2]}
dict2 = copy.deepcopy(dict1)
dict2['b'][0] = 3
print("dict1: ", dict1)
print("dict2: ", dict2)
此输出为:
dict1: {'a': 1, 'b': [1, 2]}
dict2: {'a': 1, 'b': [3, 2]}
由于使用了深拷贝,所以当我们修改dict2中的子对象时,dict1并不会受到影响。
3. 总结
在Python中,copy()和deepcopy()函数是非常有用的函数,它们可以用来创建一个对象的新副本。.copy()函数创建的是一个浅副本,也就是说只拷贝父对象,不拷贝子对象,而copy.deepcopy()函数创建的是一个深层副本,它会创建一个完全相同的对象副本,包括所有的子对象。这两个函数都可以用于复制列表和字典等嵌套对象。