如何在 Python 中复制列表(浅复制与深复制)

了解如何在 Python 中复制列表。探索列表切片、copy() 方法、列表构造函数,并掌握浅拷贝和深拷贝之间的区别。

在编辑器中尝试此解决方案

概述

在Python中,列表是可变对象,变量在内存中保存对这些对象的引用而不是实际值。这意味着,如果您将列表分配给新变量(例如“list_b = list_a”),则两个变量都引用完全相同的列表。通过“list_b”进行的任何修改都会立即影响“list_a”。为了避免这种副作用,您必须创建该列表的显式副本。

Python 提供了几种创建列表浅表副本的方法。浅拷贝构造一个新列表,其中包含对原始列表中找到的元素的引用。常见的方法包括使用内置列表 `.copy()` 方法、使用列表切片 `list_a[:]` 或将列表传递给 `list()` 构造函数。所有这些都会创建一个新的列表容器,允许您独立地附加或删除元素。

但是,如果列表包含嵌套的可变对象(例如列表或字典),则浅拷贝只会复制外部容器;嵌套对象保持共享。修改副本中的嵌套列表将更改原始列表。为了防止这种情况,您必须使用“copy”模块的“deepcopy()”函数执行深度复制,该函数递归地克隆层次结构内的每个对象。

代码和执行输出

此代码演示了引用分配陷阱、使用 list.copy() 的浅复制以及使用 copy 模块的深复制嵌套列表。

import copy

# 1. The assignment reference trap (Not a copy!)
original = [1, 2, 3]
reference = original
reference.append(99)
print("Reference modification affects original:", original)

# Reset list
original = [1, 2, 3]

# 2. Creating a shallow copy (using list.copy())
shallow_copy = original.copy()
shallow_copy.append(100)
print("\nOriginal:", original)
print("Shallow copy:", shallow_copy)

# 3. The nested list limitation of shallow copies
nested = [[1, 2], [3, 4]]
shallow_nested = nested.copy()
shallow_nested[0].append(99) # Modifying nested list
print("\nOriginal nested:", nested)
print("Shallow nested copy:", shallow_nested)

# 4. Creating a deep copy
nested_original = [[1, 2], [3, 4]]
deep_copy = copy.deepcopy(nested_original)
deep_copy[0].append(99)
print("\nOriginal nested:", nested_original)
print("Deep copy (completely independent):", deep_copy)
端子输出
Reference modification affects original: [1, 2, 3, 99]

Original: [1, 2, 3]
Shallow copy: [1, 2, 3, 100]

Original nested: [[1, 2, 99], [3, 4]]
Shallow nested copy: [[1, 2, 99], [3, 4]]

Original nested: [[1, 2], [3, 4]]
Deep copy (completely independent): [[1, 2, 99], [3, 4]]

逐步实施

  • 使用 my_list.copy() 或 my_list[:] 创建平面列表结构的浅表副本。
  • 当您需要独立集合时,请避免像 copy_list = my_list 这样的引用分配。
  • 导入 copy 模块并对包含嵌套可变结构的列表使用 copy.deepcopy(my_list) 。
  • 确保您了解数据结构以优化性能和内存占用。

常见问题解答

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

浅拷贝复制最外层的容器,但引用嵌套的可变对象。深拷贝递归地复制所有嵌套的容器和对象,从而产生完全隔离的数据结构。

列表切片 (list[:]) 比 list.copy() 更快吗?

它们的性能几乎相同,因为两者都在底层执行优化的 C 操作。为了提高可读性,通常首选使用 list.copy()。

相关主题

推荐的 Python 资源

通过相关的交互式教程、备忘单和代码比较来扩展您的知识。