在 Python 编程中,列表和字典是非常常用的数据结构。当我们需要复制这些数据结构时,经常会遇到浅拷贝(shallow copy)和深拷贝(deep copy)的概念。理解这两者的区别对于编写高效且无错误的代码非常重要。今天我们就来详细探讨一下浅拷贝和深拷贝的区别,并通过实际代码示例来帮助大家更好地理解和应用。
1. 列表的浅拷贝
浅拷贝(shallow copy)是指创建一个新的对象,但这个新对象中的元素仍然是原对象中元素的引用。这意味着如果原对象中的元素是可变类型(如列表、字典等),修改新对象中的元素会影响到原对象。
示例 1:使用 list()
方法进行浅拷贝
# 原始列表
original_list = [1, 2, [3, 4]]
# 使用 list() 方法进行浅拷贝
shallow_copied_list = list(original_list)
# 修改浅拷贝列表中的嵌套列表
shallow_copied_list[2].append(5)
print("原始列表:", original_list) # 输出: 原始列表: [1, 2, [3, 4, 5]]
print("浅拷贝列表:", shallow_copied_list) # 输出: 浅拷贝列表: [1, 2, [3, 4, 5]]
在这个例子中,shallow_copied_list
是 original_list
的浅拷贝。当我们修改 shallow_copied_list
中的嵌套列表时,original_list
也发生了变化,因为它们共享同一个嵌套列表的引用。
2. 列表的深拷贝
深拷贝(deep copy)是指创建一个新的对象,并且这个新对象中的元素也是原对象中元素的完整副本。这意味着即使原对象中的元素是可变类型,修改新对象中的元素也不会影响到原对象。
示例 2:使用 copy
模块的 deepcopy()
方法进行深拷贝
import copy
# 原始列表
original_list = [1, 2, [3, 4]]
# 使用 deepcopy() 方法进行深拷贝
deep_copied_list = copy.deepcopy(original_list)
# 修改深拷贝列表中的嵌套列表
deep_copied_list[2].append(5)
print("原始列表:", original_list) # 输出: 原始列表: [1, 2, [3, 4]]
print("深拷贝列表:", deep_copied_list) # 输出: 深拷贝列表: [1, 2, [3, 4, 5]]
在这个例子中,deep_copied_list
是 original_list
的深拷贝。当我们修改 deep_copied_list
中的嵌套列表时,original_list
不会受到影响,因为它们是完全独立的对象。
3. 字典的浅拷贝
字典的浅拷贝与列表类似,创建一个新的字典,但其中的值仍然是原字典中值的引用。
示例 3:使用 dict()
方法进行浅拷贝
# 原始字典
original_dict = {'a': 1, 'b': [2, 3]}
# 使用 dict() 方法进行浅拷贝
shallow_copied_dict = dict(original_dict)
# 修改浅拷贝字典中的嵌套列表
shallow_copied_dict['b'].append(4)
print("原始字典:", original_dict) # 输出: 原始字典: {'a': 1, 'b': [2, 3, 4]}
print("浅拷贝字典:", shallow_copied_dict) # 输出: 浅拷贝字典: {'a': 1, 'b': [2, 3, 4]}
在这个例子中,shallow_copied_dict
是 original_dict
的浅拷贝。当我们修改 shallow_copied_dict
中的嵌套列表时,original_dict
也发生了变化,因为它们共享同一个嵌套列表的引用。
4. 字典的深拷贝
字典的深拷贝与列表的深拷贝类似,创建一个新的字典,并且其中的值也是原字典中值的完整副本。
示例 4:使用 copy
模块的 deepcopy()
方法进行深拷贝
import copy
# 原始字典
original_dict = {'a': 1, 'b': [2, 3]}
# 使用 deepcopy() 方法进行深拷贝
deep_copied_dict = copy.deepcopy(original_dict)
# 修改深拷贝字典中的嵌套列表
deep_copied_dict['b'].append(4)
print("原始字典:", original_dict) # 输出: 原始字典: {'a': 1, 'b': [2, 3]}
print("深拷贝字典:", deep_copied_dict) # 输出: 深拷贝字典: {'a': 1, 'b': [2, 3, 4]}
在这个例子中,deep_copied_dict
是 original_dict
的深拷贝。当我们修改 deep_copied_dict
中的嵌套列表时,original_dict
不会受到影响,因为它们是完全独立的对象。
5. 实战案例:管理学生信息
假设我们有一个学生信息管理系统,每个学生的信息包括姓名、年龄和课程列表。我们需要实现一个功能,将一个学生的信息复制给另一个学生,但不希望修改新学生的课程列表时影响到原学生的课程列表。
示例 5:使用深拷贝管理学生信息
import copy
class Student:
def __init__(self, name, age, courses):
self.name = name
self.age = age
self.courses = courses
def add_course(self, course):
self.courses.append(course)
def __str__(self):
return f"Student: {self.name}, Age: {self.age}, Courses: {self.courses}"
# 创建一个学生对象
student1 = Student("Alice", 20, ["Math", "Science"])
# 使用深拷贝复制学生对象
student2 = copy.deepcopy(student1)
# 修改新学生对象的课程列表
student2.add_course("History")
print("学生1:", student1) # 输出: 学生1: Student: Alice, Age: 20, Courses: ['Math', 'Science']
print("学生2:", student2) # 输出: 学生2: Student: Alice, Age: 20, Courses: ['Math', 'Science', 'History']
在这个例子中,我们使用 deepcopy()
方法将 student1
的信息复制给 student2
。当我们为 student2
添加新的课程时,student1
的课程列表不会受到影响,因为它们是完全独立的对象。
总结
本文详细介绍了 Python 中列表和字典的浅拷贝和深拷贝的区别,并通过实际代码示例展示了如何使用 list()
、dict()
和 copy
模块的 deepcopy()
方法进行浅拷贝和深拷贝。浅拷贝创建的是新对象,但其中的元素仍然是原对象中元素的引用,而深拷贝创建的是新对象及其元素的完整副本。
好了,今天的分享就到这里了,我们下期见。如果本文对你有帮助,请动动你可爱的小手指点赞、转发、在看吧!
付费合集推荐
文末福利
公众号消息窗口回复“编程资料”,获取Python编程、人工智能、爬虫等100+本精品电子书。