在读取dict.copy()的文档时,它说它对字典做了一个浅拷贝。我正在阅读的这本书(Beazley's Python Reference)也是如此,它说:
m.copy()方法创建了一个浅的
项中包含的项目的副本
对象的映射,并将它们放在
新建映射对象。
考虑一下:
>>> original = dict(a=1, b=2)
>>> new = original.copy()
>>> new.update({'c': 3})
>>> original
{'a': 1, 'b': 2}
>>> new
{'a': 1, 'c': 3, 'b': 2}
所以我假设这将更新原始的值(并添加'c': 3),因为我正在做一个浅拷贝。比如,如果你做一个列表:
>>> original = [1, 2, 3]
>>> new = original
>>> new.append(4)
>>> new, original
([1, 2, 3, 4], [1, 2, 3, 4])
这与预期的一样。
既然两者都是浅拷贝,为什么dict.copy()不像我期望的那样工作?或者我对浅复制和深复制的理解是有缺陷的?
通过“浅复制”,它意味着字典的内容不按值复制,而只是创建一个新的引用。
>>> a = {1: [1,2,3]}
>>> b = a.copy()
>>> a, b
({1: [1, 2, 3]}, {1: [1, 2, 3]})
>>> a[1].append(4)
>>> a, b
({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})
相比之下,深度复制将按值复制所有内容。
>>> import copy
>>> c = copy.deepcopy(a)
>>> a, c
({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})
>>> a[1].append(5)
>>> a, c
({1: [1, 2, 3, 4, 5]}, {1: [1, 2, 3, 4]})
So:
b = a:引用赋值,使a和b指向同一个对象。
b = a.copy():浅复制,a和b将成为两个独立的对象,但它们的内容仍然共享相同的引用
b = copy.deepcopy(a):深度复制,a和b的结构和内容完全隔离。
举个例子:
original = dict(a=1, b=2, c=dict(d=4, e=5))
new = original.copy()
现在让我们在“shallow”(第一个)层中改变一个值:
new['a'] = 10
# new = {'a': 10, 'b': 2, 'c': {'d': 4, 'e': 5}}
# original = {'a': 1, 'b': 2, 'c': {'d': 4, 'e': 5}}
# no change in original, since ['a'] is an immutable integer
现在让我们改变一个更深层次的值:
new['c']['d'] = 40
# new = {'a': 10, 'b': 2, 'c': {'d': 40, 'e': 5}}
# original = {'a': 1, 'b': 2, 'c': {'d': 40, 'e': 5}}
# new['c'] points to the same original['d'] mutable dictionary, so it will be changed