简介
在Python中,对象的拷贝可以是浅拷贝(shallow copy)或深拷贝(deep copy),这两者之间的主要区别在于它们处理复合对象(如列表、字典或其他包含其他对象的对象)的方式不同。
浅拷贝(Shallow Copy):
浅拷贝会创建一个新对象,但这个新对象包含的是对原始对象中元素的引用,而不是元素本身的拷贝。因此,如果原始对象中的元素是可变的,并且在新对象或原始对象中修改了这些元素,那么这些更改将反映在另一个对象中,因为它们引用的是相同的对象。
在Python中,可以使用copy模块的copy()函数或列表的切片操作(对于列表)来实现浅拷贝。
深拷贝(Deep Copy):
深拷贝会创建一个新对象,并且递归地拷贝原始对象中的所有元素以及这些元素所包含的所有对象。这样,新对象和原始对象将完全独立,修改其中一个对象不会影响到另一个对象。
在Python中,可以使用copy模块的deepcopy()函数来实现深拷贝。
python传参(list/array/dict等类型)时
在Python中,列表(List)是可变对象。这意味着如果你将一个列表传入一个函数,并在函数内部修改了该列表的值,那么在函数外部的原始列表也会发生相应的变化。这是因为列表是通过引用传递的,而不是通过值传递的。
下面是一个简单的示例,演示了如何在函数内部修改列表,并观察到函数外部的变化:
def modify_list(lst):
lst.append(4) # 在函数内部修改列表
my_list = [1, 2, 3]
print("原始列表:", my_list)
modify_list(my_list)
print("修改后的列表:", my_list)
输出结果:
原始列表: [1, 2, 3]
修改后的列表: [1, 2, 3, 4]
可以看到,在modify_list函数内部,我们将数字4添加到了列表lst的末尾。由于lst实际上是对my_list的引用,因此在函数外部,my_list也发生了相应的变化,末尾添加了数字4。
NumPy库中的数组切片时
如果你在使用NumPy库中的数组,并对其进行切分,那么切分出来的数组将共享同一块数据内存。这意味着,如果你修改了切分后的数组中的元素,原数组对应位置的元素也会跟着改变,因为它们是同一个数据块的不同视图。
python
import numpy as np
original_array = np.array([1, 2, 3, 4])
sliced_array = original_array[2:]
sliced_array[0] = 999
print(original_array)
输出: [ 1 2 999 4],原数组也被修改了
在这个NumPy的例子中,修改sliced_array直接导致original_array中相应位置的元素被改变,因为它们共享数据内存。torch.Tensor同理。