面试题:Python 中的深拷贝和浅拷贝有什么区别?

面试题:Python 中的深拷贝和浅拷贝有什么区别?

编码文章call10242025-01-12 12:05:2824A+A-

在 Python 中,当你复制一个对象时,可能会遇到“浅拷贝”和“深拷贝”这两个术语。它们听起来相似,但实际上有很大的区别,理解它们的差异可以避免在代码中引发不必要的错误。接下来,我将通过简单的例子为你讲解它们的区别。

1. 浅拷贝(Shallow Copy)

浅拷贝是指创建一个新的对象,但对象中的元素仍然是原始对象的引用。也就是说,浅拷贝并没有递归地复制对象内部的嵌套对象,而是保留了这些嵌套对象的引用。因此,改变拷贝对象中的嵌套元素,会影响到原始对象。

示例:

import copy

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

# 使用浅拷贝
shallow_copy = copy.copy(original_list)

# 修改浅拷贝中的嵌套元素
shallow_copy[1][0] = 99

print("原始列表:", original_list)        # 输出: 原始列表: [1, [99, 3], 4]
print("浅拷贝列表:", shallow_copy)         # 输出: 浅拷贝列表: [1, [99, 3], 4]

在上面的代码中,shallow_copy 是对 original_list 的浅拷贝。尽管 shallow_copy 是一个新的列表,但它的第二个元素(即子列表 [2, 3])仍然指向原始列表中的子列表。因此,修改嵌套列表中的元素(例如 shallow_copy[1][0] = 99)也会改变原始列表中的嵌套元素。

2. 深拷贝(Deep Copy)

深拷贝则创建一个新的对象,并且递归地复制原始对象及其内部的所有嵌套对象。也就是说,深拷贝不仅仅复制最外层的对象,还会复制对象内的所有子对象,这样修改拷贝对象不会影响原始对象。

示例:

import copy

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

# 使用深拷贝
deep_copy = copy.deepcopy(original_list)

# 修改深拷贝中的嵌套元素
deep_copy[1][0] = 99

print("原始列表:", original_list)        # 输出: 原始列表: [1, [2, 3], 4]
print("深拷贝列表:", deep_copy)           # 输出: 深拷贝列表: [1, [99, 3], 4]

在这个例子中,deep_copy 是对 original_list 的深拷贝。由于深拷贝会递归复制所有嵌套对象,修改 deep_copy 中的嵌套列表并不会影响到原始列表中的元素。

3. global 和 nonlocal 的区别

  • 浅拷贝
    • 创建新对象,但只复制对象的引用。内部嵌套的对象仍然共享。
    • 修改拷贝对象中的嵌套元素会影响原始对象。
    • 适用于拷贝没有嵌套或者只需要拷贝顶层元素的对象。
  • 深拷贝
    • 创建新对象并递归复制所有嵌套对象。
    • 修改拷贝对象的任何元素不会影响原始对象。
    • 适用于需要完全独立的拷贝,尤其是当对象包含嵌套对象时。

实际应用场景:

  • 浅拷贝:通常适用于浅层对象的拷贝(如单层列表或字典),当你只关心顶层对象而不修改内部嵌套对象时,浅拷贝是一个更高效的选择。
  • 深拷贝:如果你的对象包含复杂的嵌套结构(如嵌套列表或字典),并且你希望对原始对象进行完全的独立复制,避免修改拷贝对象时影响原始对象,则使用深拷贝。

理解这两者的差异,有助于你在编写 Python 程序时做出更合适的选择,避免不必要的 bug。

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4