Python 中深拷贝和浅拷贝有什么区别?

2024-08-24 22:27:01 332
在Python中,深拷贝和浅拷贝都是用来复制对象的方式,但它们在处理嵌套对象(如列表中的列表,或字典中的字典)时有所不同。下面我用通俗的解释和示例来说明它们的区别。

浅拷贝(Shallow Copy)

浅拷贝创建了一个新的对象,但对原始对象中的元素,它们的引用(即地址)被复制到新对象中,而不是复制元素本身。因此,浅拷贝仅复制了对象的“第一层”内容,而嵌套的对象仍然指向原来的内存地址。

示例:

import copy

original = [[1, 2, 3], [4, 5, 6]]
shallow_copy = copy.copy(original)  # 创建一个浅拷贝

# 修改浅拷贝中的元素
shallow_copy[0][0] = 'A'

print("Original:", original)  # 输出 Original: [['A', 2, 3], [4, 5, 6]]
print("Shallow Copy:", shallow_copy)  # 输出 Shallow Copy: [['A', 2, 3], [4, 5, 6]]

在这个示例中,shallow_copyoriginal 的浅拷贝。由于浅拷贝只是复制了引用,当我们修改 shallow_copy 中的嵌套列表内容时,original 中对应的内容也被改变了。

深拷贝(Deep Copy)

深拷贝不仅创建了一个新的对象,还递归地复制了所有嵌套对象的内容。因此,深拷贝会创建一个完全独立的副本,改变副本不会影响原始对象。

示例:

import copy

original = [[1, 2, 3], [4, 5, 6]]
deep_copy = copy.deepcopy(original)  # 创建一个深拷贝

# 修改深拷贝中的元素
deep_copy[0][0] = 'A'

print("Original:", original)  # 输出 Original: [[1, 2, 3], [4, 5, 6]]
print("Deep Copy:", deep_copy)  # 输出 Deep Copy: [['A', 2, 3], [4, 5, 6]]

在这个示例中,deep_copyoriginal 的深拷贝。因为深拷贝复制了所有嵌套对象,所以当我们修改 deep_copy 中的嵌套列表内容时,original 并不会受到影响。

总结对比

  • 浅拷贝:仅复制对象的第一层内容,嵌套对象的引用仍指向原来的内存地址。因此,修改浅拷贝中的嵌套对象会影响原始对象。
  • 深拷贝:递归复制所有嵌套对象,生成一个完全独立的副本。因此,修改深拷贝中的内容不会影响原始对象。

使用场景

  • 浅拷贝:适用于当对象中的元素是不可变类型(如整数、字符串、元组)或者你确定不需要独立的副本时。
  • 深拷贝:适用于当你需要一个完全独立的副本,并且对象中包含可变类型(如列表、字典)时。