导入 copya = \'deepak\'b = 1, 2, 3, 4c = [1, 2, 3, 4]d = {1: 10, 2: 20, 3: 30}a1 = copy.copy(a)b1 = copy.copy(b)c1 = copy.copy(c)d1 = copy.copy(d) print(\'immutable - id(a)==id(a1)\', id(a...
import copy
a = "deepak"
b = 1, 2, 3, 4
c = [1, 2, 3, 4]
d = {1: 10, 2: 20, 3: 30}
a1 = copy.copy(a)
b1 = copy.copy(b)
c1 = copy.copy(c)
d1 = copy.copy(d)
print("immutable - id(a)==id(a1)", id(a) == id(a1))
print("immutable - id(b)==id(b1)", id(b) == id(b1))
print("mutable - id(c)==id(c1)", id(c) == id(c1))
print("mutable - id(d)==id(d1)", id(d) == id(d1))
我得到以下结果:
immutable - id(a)==id(a1) True
immutable - id(b)==id(b1) True
mutable - id(c)==id(c1) False
mutable - id(d)==id(d1) False
如果我执行深度复制:
a1 = copy.deepcopy(a)
b1 = copy.deepcopy(b)
c1 = copy.deepcopy(c)
d1 = copy.deepcopy(d)
结果是一样的:
immutable - id(a)==id(a1) True
immutable - id(b)==id(b1) True
mutable - id(c)==id(c1) False
mutable - id(d)==id(d1) False
如果我进行赋值操作:
a1 = a
b1 = b
c1 = c
d1 = d
结果是:
immutable - id(a)==id(a1) True
immutable - id(b)==id(b1) True
mutable - id(c)==id(c1) True
mutable - id(d)==id(d1) True
有人能解释一下这些副本之间到底有什么区别吗?这和可变和不可变对象有关吗?如果是的话,你能给我解释一下吗?
要点如下:使用“正常赋值”处理浅列表(没有子列表,只有单个元素)会产生“副作用”,当您创建浅列表,然后使用“正常赋值”创建此列表的副本时。此“副作用”是当您更改所创建的副本列表的任何元素时,因为它会自动更改原始列表中的相同元素。这时就 copy
派上用场了,因为在更改复制元素时不会更改原始列表元素。
另一方面, copy
当您有一个包含列表的列表(子列表)并解决它时,也会产生“副作用” deepcopy
。例如,如果您创建一个包含嵌套列表的大列表(子列表),并且创建此大列表(原始列表)的副本。当您修改复制列表的子列表时,就会出现“副作用”,这会自动修改大列表的子列表。有时(在某些项目中)您希望保持大列表(您的原始列表)原样而不进行修改,而您想要的只是复制其元素(子列表)。为此,您的解决方案是使用 deepcopy
可以处理此“副作用”并在不修改原始内容的情况下进行复制的解决方案。
和 copy
的不同行为 deep copy
仅涉及复合对象(即:包含其他对象的对象,例如列表)。
以下是此简单代码示例中说明的差异:
第一的
让我们 copy
通过创建一个原始列表和该列表的副本来检查 (shallow) 的行为:
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 子元素 自动修改 copy_list 子元素
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 子元素 自动修改 original_list 子元素
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 子元素不会修改 copy_list 子元素
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 子元素不会修改 original_list 子元素
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]