浅拷贝是指创建一个新的对象,但对于对象内部的元素(如列表、字典中的项等),只是引用了原始对象中的元素,而不是创建新的元素。
因此,浅拷贝的对象与原始对象共享内部的可变元素。如果修改了内部元素的值,两个对象都会受到影响。
浅拷贝常通过以下几种方式实现:
copy.copy()
:通过 copy
模块的 copy()
函数创建浅拷贝。list.copy()
:对于列表,可以使用 list.copy()
方法。dict.copy()
:对于字典,可以使用 dict.copy()
方法。[:]
:通过切片创建一个浅拷贝。import copy
# 使用 copy.copy()
original = [[1, 2], [3, 4]] # 内部元素是列表,列表是可变元素
shallow_copy = copy.copy(original)
# 修改 shallow_copy 中的内部元素
shallow_copy[0][0] = 6
# 观察两个对象的变化
print("Original:", original) # Original: [[6, 2], [3, 4]]
print("Shallow Copy:", shallow_copy) # Shallow Copy: [[6, 2], [3, 4]]
original
和 shallow_copy
是两个独立的对象,但它们的内部列表是共享的。shallow_copy
中的内部列表元素(shallow_copy[0][0] = 6
)也会影响 original
中的相应元素,因为它们指向相同的内部列表。注意,如果内部元素不是可变元素,那么不改变原来的常数值。
import copy
original = [1,2]
shallow_copy = copy.copy(original)
shallow_copy[0]= 6
print("Original:", original) # Original: [1, 2]
print("Shallow Copy:", shallow_copy) # Shallow Copy: [6, 2]
列表切片:new_list = old_list[:]
创建一个新列表,但其中的元素依然是对原始元素的引用。
original = [1, [2, 3]]
shallow_copy = original[:]
shallow_copy[1][0] = 999
print("Original:", original) # Original: [1, [999, 3]]
深拷贝是指创建一个新的对象,同时递归地创建对象中所有嵌套对象的副本。
深拷贝的对象与原始对象完全独立,不共享任何子对象。修改深拷贝中的元素不影响原始对象,反之亦然。
深拷贝通过 copy.deepcopy()
函数实现。该函数会递归地创建一个新对象,并复制所有的嵌套对象,确保每一层都是新的对象。
import copy
# 使用 copy.deepcopy()
original = [[1, 2], [3, 4]]
deep_copy = copy.deepcopy(original)
# 修改 deep_copy 中的内部元素
deep_copy[0][0] = 999
# 观察两个对象的变化
print("Original:", original) # Original: [[1, 2], [3, 4]]
print("Deep Copy:", deep_copy) # Deep Copy: [[999, 2], [3, 4]]
在这个例子中,original
和 deep_copy
完全独立。修改 deep_copy
中的元素不会影响到 original
,因为它们是完全独立的对象。
特性 | 浅拷贝 (Shallow Copy) | 深拷贝 (Deep Copy) |
---|---|---|
拷贝方式 | 创建新的对象,但对象内部的元素还是原对象的引用 | 创建一个新的对象及其所有嵌套对象的副本 |
内部对象共享 | 内部对象是共享的,即它们指向相同的内存位置 | 内部对象完全独立,不共享任何内存 |
修改内部对象的影响 | 修改拷贝中的内部对象会影响原对象 | 修改拷贝中的内部对象不会影响原对象 |
速度 | 通常比深拷贝快,因为不递归拷贝所有嵌套对象 | 比浅拷贝慢,因为需要递归地拷贝所有对象 |
import copy
# 创建原始对象
original = {
'a': 1,
'b': [2, 3],
'c': {'nested': 4}
}
# 浅拷贝
shallow_copy = copy.copy(original)
shallow_copy['b'][0] = 999 # 修改列表中的元素
# 深拷贝
deep_copy = copy.deepcopy(original)
deep_copy['c']['nested'] = 999 # 修改嵌套字典中的元素
print("Original:", original)
print("Shallow Copy:", shallow_copy)
print("Deep Copy:", deep_copy)
输出:
Original: {'a': 1, 'b': [999, 3], 'c': {'nested': 4}}
Shallow Copy: {'a': 1, 'b': [999, 3], 'c': {'nested': 4}}
Deep Copy: {'a': 1, 'b': [999, 3], 'c': {'nested': 999}}
b
列表中的元素会影响原始对象,因为它们共享相同的列表。c
字典中的嵌套对象(nested
)不会影响原始对象,因为 deepcopy
创建了完全独立的副本。