Python 浅拷贝和深拷贝区别
引言
在 Python 编程中,了解浅拷贝和深拷贝之间的区别对于有效管理和处理数据至关重要。本篇文章将深入探讨这两者之间的差异,解释它们的工作原理和适用场景。
浅拷贝
浅拷贝是指创建一个新对象,该新对象指向与原始对象相同的内存地址。通过浅拷贝创建的对象被称为原始对象的引用。当对原始对象进行任何更改时,这些更改也会反映在新对象中。
使用 Python 的 copy
模块中的 copy()
函数可以创建浅拷贝:
“`python
import copy
original = [1, 2, 3]
shallow_copy = copy.copy(original)
“`
示例中,shallow_copy
是 original
的浅拷贝。对 original
中的任何元素进行更改,都会反映在 shallow_copy
中:
python
original[1] = 5
print(shallow_copy) # 输出:[1, 5, 3]
深拷贝
与浅拷贝不同,深拷贝创建了一个新对象,其中包含原始对象数据的副本。对原始对象进行的任何更改都不会影响新创建的对象。
可以使用 Python 的 copy
模块中的 deepcopy()
函数创建深拷贝:
python
deep_copy = copy.deepcopy(original)
示例中,deep_copy
是 original
的深拷贝。对 original
中的任何元素进行更改,都不会影响 deep_copy
:
python
original[1] = 7
print(deep_copy) # 输出:[1, 2, 3]
浅拷贝和深拷贝的差异
以下表格总结了浅拷贝和深拷贝之间的主要差异:
| 特征 | 浅拷贝 | 深拷贝 |
|—|—|—|
| 内存地址 | 指向与原始对象相同的地址 | 创建新的地址 |
| 更改 | 对原始对象的更改也会影响新对象 | 对原始对象的更改不会影响新对象 |
| 数据结构 | 仅复制原始对象引用 | 复制原始对象及其嵌套数据结构 |
| 速度和内存开销 | 速度快,内存开销低(仅复制引用) | 速度慢,内存开销高(复制所有数据) |
何时使用浅拷贝
浅拷贝适用于不需要创建原始对象完全独立副本的情况,例如:
- 当对象是不可变的(例如字符串)
- 当对象很大,进行深拷贝代价高昂时
- 当需要在不同的内存区域共享数据时
何时使用深拷贝
深拷贝适用于需要创建原始对象完全独立副本的情况,例如:
- 当对象是可变的(例如列表或字典)
- 当需要防止对原始对象的更改影响新对象时
- 当需要在不同的进程或线程中使用对象时
实战场景
场景 1:修改列表
“`python
original_list = [1, 2, 3]
浅拷贝
shallowcopylist = originallist.copy()
shallowcopy_list[0] = 4
深拷贝
deepcopylist = copy.deepcopy(originallist)
deepcopy_list[1] = 5
print(originallist) # 输出:[1, 2, 3]
print(shallowcopylist) # 输出:[4, 2, 3]
print(deepcopy_list) # 输出:[1, 5, 3]
“`
在这个场景中,浅拷贝修改了原始列表的第一个元素,因为浅拷贝只复制了引用。而深拷贝创建了原始列表的完全副本,因此修改深拷贝不会影响原始列表。
场景 2:嵌套数据结构
“`python
original_dict = {
“name”: “John”,
“age”: 30,
“address”: {“city”: “New York”, “street”: “Main Street”}
}
浅拷贝
shallowcopydict = originaldict.copy()
shallowcopy_dict[“address”][“street”] = “Park Avenue”
深拷贝
deepcopydict = copy.deepcopy(originaldict)
deepcopy_dict[“address”][“city”] = “Los Angeles”
print(original_dict)
输出:
{
“name”: “John”,
“age”: 30,
“address”: {“city”: “New York”, “street”: “Park Avenue”}
}
print(shallowcopydict)
输出:
{
“name”: “John”,
“age”: 30,
“address”: {“city”: “New York”, “street”: “Park Avenue”}
}
print(deepcopydict)
输出:
{
“name”: “John”,
“age”: 30,
“address”: {“city”: “Los Angeles”, “street”: “Main Street”}
}
“`
在这个场景中,浅拷贝修改了嵌套数据结构(地址)的 street
字段。而深拷贝创建了嵌套数据结构的完整副本,因此修改深拷贝不会影响原始数据结构。
问答
浅拷贝和深拷贝的区别是什么?
- 浅拷贝创建一个新对象,该对象指向与原始对象相同的内存地址,而深拷贝创建一个新对象,其中包含原始对象数据的副本。
何时使用浅拷贝?
- 当对象是不可变的,或者当需要在不同的内存区域共享数据时使用浅拷贝。
何时使用深拷贝?
- 当对象是可变的,或者当需要防止对原始对象的更改影响新对象时使用深拷贝。
浅拷贝如何影响原始对象?
- 对原始对象的任何更改也会反映在新创建的对象中。
深拷贝如何影响原始对象?
- 对原始对象的任何更改都不会影响新创建的对象。
原创文章,作者:魏景忆,如若转载,请注明出处:https://www.wanglitou.cn/article_88321.html