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

相关推荐
IT科技那点事儿3 分钟前
引领AI安全新时代 Accelerate 2025北亚巡展·北京站成功举办
人工智能·安全
databook10 分钟前
概率图模型:机器学习的结构化概率之道
python·机器学习·scikit-learn
新智元11 分钟前
美 IT 业裁员狂飙 35%,「硅谷梦」彻底崩塌!打工人怒喷 PIP
人工智能·openai
新智元13 分钟前
乔布斯挚友去世!胰腺癌再夺硅谷天才,曾写下苹果「创世代码」
人工智能·openai
拾回程序猿的圈圈∞13 分钟前
实战二:开发网页端界面完成黑白视频转为彩色视频
python·ai编程
亚林瓜子15 分钟前
AWS Elastic Beanstalk + CodePipeline(Python Flask Web的国区CI/CD)
python·ci/cd·flask·web·aws·beanstalk·codepipeline
春末的南方城市16 分钟前
中山大学&美团&港科大提出首个音频驱动多人对话视频生成MultiTalk,输入一个音频和提示,即可生成对应唇部、音频交互视频。
人工智能·python·深度学习·计算机视觉·transformer
春末的南方城市19 分钟前
Ctrl-Crash 助力交通安全:可控生成逼真车祸视频,防患于未然
人工智能·计算机视觉·自然语言处理·aigc·音视频
程序边界25 分钟前
全球人工智能技术大会(GAITC 2025):技术前沿与产业融合的深度交响
人工智能
OpenCSG32 分钟前
电子行业AI赋能软件开发经典案例——某金融软件公司
人工智能·算法·金融·开源