要采取的 GIST 是这样的:使用“正常分配”处理浅表(没有子列表,只有单个元素)会在您创建浅表然后使用“正常分配”创建此列表的副本时产生“副作用” . 这种“副作用”是当您更改创建的副本列表的任何元素时,因为它会自动更改原始列表的相同元素。这时候copy
就派上用场了,因为它在更改复制元素时不会更改原始列表元素。
另一方面,当您有一个包含列表的列表(sub_lists)并解决它copy
时,它也确实有“副作用” 。deepcopy
例如,如果您创建一个包含嵌套列表的大列表(sub_lists),并创建此大列表(原始列表)的副本。当您修改复制列表的 sub_lists 时会出现“副作用”,这会自动修改大列表的 sub_lists。有时(在某些项目中)您希望保持大列表(您的原始列表)不变,并且您想要的只是复制其元素(sub_lists)。为此,您的解决方案是使用deepcopy
which 将处理这种“副作用”并在不修改原始内容的情况下制作副本。
不同的行为copy
和deep copy
操作只涉及复合对象(即:包含其他对象的对象,例如列表)。
以下是此简单代码示例中说明的差异:
第一的
让我们通过创建一个原始列表和该列表的副本来检查copy
(浅)行为:
import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.copy(original_list)
现在,让我们运行一些print
测试,看看原始列表与其副本列表相比如何表现:
original_list 和 copy_list 有不同的地址
print(hex(id(original_list)), hex(id(copy_list))) # 0x1fb3030 0x1fb3328
original_list 和 copy_list 的元素具有相同的地址
print(hex(id(original_list[1])), hex(id(copy_list[1]))) # 0x537ed440 0x537ed440
original_list 和 copy_list 的子元素具有相同的地址
print(hex(id(original_list[5])), hex(id(copy_list[5]))) # 0x1faef08 0x1faef08
修改 original_list 元素不会修改 copy_list 元素
original_list.append(6)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b']]
修改 copy_list 元素不会修改 original_list 元素
copy_list.append(7)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]
修改 original_list sub_elements 自动修改 copy_list sub_elements
original_list[5].append('c')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 7]
修改 copy_list sub_elements 自动修改 original_list sub_elements
copy_list[5].append('d')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 7]
第二
deepcopy
让我们通过做与我们所做的相同的事情来检查行为方式copy
(创建一个原始列表和该列表的副本):
import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.copy(original_list)
现在,让我们运行一些print
测试,看看原始列表与其副本列表相比如何表现:
import copy
original_list = [1, 2, 3, 4, 5, ['a', 'b']]
copy_list = copy.deepcopy(original_list)
original_list 和 copy_list 有不同的地址
print(hex(id(original_list)), hex(id(copy_list))) # 0x1fb3030 0x1fb3328
original_list 和 copy_list 的元素具有相同的地址
print(hex(id(original_list[1])), hex(id(copy_list[1]))) # 0x537ed440 0x537ed440
original_list 和 copy_list 的子元素地址不同
print(hex(id(original_list[5])), hex(id(copy_list[5]))) # 0x24eef08 0x24f3300
修改 original_list 元素不会修改 copy_list 元素
original_list.append(6)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b']]
修改 copy_list 元素不会修改 original_list 元素
copy_list.append(7)
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]
修改 original_list sub_elements 不会修改 copy_list sub_elements
original_list[5].append('c')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b'], 7]
修改 copy_list sub_elements 不会修改 original_list sub_elements
copy_list[5].append('d')
print("original_list is:", original_list) # original_list is: [1, 2, 3, 4, 5, ['a', 'b', 'c', 'd'], 6]
print("copy_list is:", copy_list) # copy_list is: [1, 2, 3, 4, 5, ['a', 'b', 'd'], 7]