Python 之深浅 Copy(十一)

Python 之深浅 Copy

一、引言

在 Python 编程里,对数据进行复制是常见操作。不过复制存在浅复制(shallow copy)和深复制(deep copy)之分,二者有着不同的实现原理与应用场景。理解深浅复制的区别,对避免数据意外修改、优化代码性能极为关键。本文会深入剖析 Python 中深浅复制的原理,借助丰富的代码示例来加深理解。

二、浅复制(Shallow Copy)

2.1 浅复制的定义

浅复制创建一个新对象,新对象里包含的元素是原对象元素的引用。对于不可变对象,新对象和原对象引用的是同一内存地址;对于可变对象,新对象和原对象中的可变对象也指向同一内存地址。

2.2 实现浅复制的方法

2.2.1 使用切片操作
python 复制代码
# 定义一个包含可变对象(列表)的列表
original_list = [1, 2, [3, 4]]
# 使用切片操作创建浅复制的列表
shallow_copy_list = original_list[:]
# 打印原始列表及其内存地址
print("原始列表:", original_list, "内存地址:", id(original_list))
# 打印浅复制列表及其内存地址
print("浅复制列表:", shallow_copy_list, "内存地址:", id(shallow_copy_list))

# 修改原始列表中的不可变元素
original_list[0] = 10
# 打印修改后原始列表
print("修改原始列表不可变元素后,原始列表:", original_list)
# 打印修改后浅复制列表
print("修改原始列表不可变元素后,浅复制列表:", shallow_copy_list)

# 修改原始列表中的可变元素
original_list[2][0] = 30
# 打印修改后原始列表
print("修改原始列表可变元素后,原始列表:", original_list)
# 打印修改后浅复制列表
print("修改原始列表可变元素后,浅复制列表:", shallow_copy_list)

在上述代码中,通过切片操作 original_list[:] 创建了浅复制列表 shallow_copy_list。当修改原始列表中的不可变元素(如 original_list[0])时,浅复制列表不受影响;但当修改原始列表中的可变元素(如 original_list[2][0])时,浅复制列表中对应的元素也会改变,这是因为它们引用的是同一个可变对象。

2.2.2 使用 copy 模块的 copy 函数
python 复制代码
import copy

# 定义一个包含可变对象(字典)的字典
original_dict = {'a': 1, 'b': {'c': 2}}
# 使用 copy 模块的 copy 函数创建浅复制的字典
shallow_copy_dict = copy.copy(original_dict)
# 打印原始字典及其内存地址
print("原始字典:", original_dict, "内存地址:", id(original_dict))
# 打印浅复制字典及其内存地址
print("浅复制字典:", shallow_copy_dict, "内存地址:", id(shallow_copy_dict))

# 修改原始字典中的不可变元素
original_dict['a'] = 10
# 打印修改后原始字典
print("修改原始字典不可变元素后,原始字典:", original_dict)
# 打印修改后浅复制字典
print("修改原始字典不可变元素后,浅复制字典:", shallow_copy_dict)

# 修改原始字典中的可变元素
original_dict['b']['c'] = 20
# 打印修改后原始字典
print("修改原始字典可变元素后,原始字典:", original_dict)
# 打印修改后浅复制字典
print("修改原始字典可变元素后,浅复制字典:", shallow_copy_dict)

此代码使用 copy.copy() 函数对字典进行浅复制。和切片操作类似,修改原始字典中的不可变元素不影响浅复制字典,而修改可变元素会同时改变浅复制字典中的对应元素。

三、深复制(Deep Copy)

3.1 深复制的定义

深复制会递归地复制原对象及其所有嵌套的对象,创建一个完全独立的新对象。新对象和原对象在内存中是完全分离的,对新对象的任何修改都不会影响原对象,反之亦然。

3.2 实现深复制的方法

使用 copy 模块的 deepcopy 函数。

python 复制代码
import copy

# 定义一个包含多层嵌套可变对象的列表
original_nested_list = [1, [2, [3, 4]]]
# 使用 copy 模块的 deepcopy 函数创建深复制的列表
deep_copy_list = copy.deepcopy(original_nested_list)
# 打印原始嵌套列表及其内存地址
print("原始嵌套列表:", original_nested_list, "内存地址:", id(original_nested_list))
# 打印深复制列表及其内存地址
print("深复制列表:", deep_copy_list, "内存地址:", id(deep_copy_list))

# 修改原始嵌套列表中的可变元素
original_nested_list[1][1][0] = 30
# 打印修改后原始嵌套列表
print("修改原始嵌套列表可变元素后,原始嵌套列表:", original_nested_list)
# 打印修改后深复制列表
print("修改原始嵌套列表可变元素后,深复制列表:", deep_copy_list)

在这个代码中,使用 copy.deepcopy() 函数对多层嵌套的列表进行深复制。当修改原始嵌套列表中的可变元素时,深复制列表不受影响,因为它们是完全独立的对象。

四、浅复制与深复制的应用场景

4.1 浅复制的应用场景

浅复制适用于仅需复制对象的顶层结构,且不希望创建过多对象占用大量内存的情况。例如,在数据展示或简单的数据传递中,若不需要对嵌套对象进行修改,使用浅复制可以节省内存。

4.2 深复制的应用场景

深复制适用于需要完全独立于原对象的情况,以避免因对象引用而导致的数据意外修改。例如,在多线程编程中,为了防止不同线程对同一对象进行修改产生冲突,可使用深复制创建独立的对象副本。

五、总结与展望

5.1 总结

Python 中的浅复制和深复制是两种不同的数据复制方式。浅复制只复制对象的顶层结构,对于嵌套的可变对象,新对象和原对象共享引用;深复制则递归地复制所有嵌套对象,创建完全独立的新对象。在实际编程中,应根据具体需求选择合适的复制方式,避免数据意外修改和不必要的内存开销。

5.2 展望

随着 Python 在数据处理、机器学习等领域的广泛应用,对数据复制的效率和准确性要求会越来越高。未来可能会有更高效的深浅复制算法和实现方式出现,同时也需要开发者更加深入地理解和运用这些概念,以提高代码的性能和可靠性。

相关推荐
IceTeapoy2 小时前
【RL】强化学习入门(二):Q-Learning算法
人工智能·算法·强化学习
_一条咸鱼_6 小时前
Python 之数字类型内置方法(十四)
人工智能·python·面试
满怀10156 小时前
【Python进阶】正则表达式实战指南:从基础到高阶应用
开发语言·python·正则表达式
_一条咸鱼_6 小时前
Python 之集合类型内置方法(十九)
人工智能·python·面试
_一条咸鱼_6 小时前
Python 之列表类型内置方法(十六)
人工智能·python·面试
_一条咸鱼_6 小时前
Python 格式化字符串的 4 种方式(十三)
人工智能·python·面试
訾博ZiBo6 小时前
AI日报 - 2025年04月24日
人工智能
_一条咸鱼_6 小时前
Python 之元组类型内置方法(十七)
人工智能·python·面试
_一条咸鱼_6 小时前
Python 小数据池与代码块深入剖析(十二)
人工智能·python·面试