理解dict.copy() - shadow 还是 deep?
Posted on 2015-3-11 in Code
最近在重新设计一段代码的时候,发现有一行使用dict.copy()的方式复制一个字典,第一反应是会和list一样,对新dict的任何操作都会影响原有的dict,结果实验了一下并不是这样。
>>> a = {'a':111, 'b':222}
>>> b = a.copy()
>>> b['c'] = 333
>>> del b['a']
>>> print a
>>> {'a': 111, 'b': 222}
>>> print b
>>> {'c': 333, 'b': 222}
这让我很困惑,为什么浅复制(shadow copy)的情况和list不一样。。。
在StackOverflow上找到了一个回答,解答了我的疑惑,大致描述一下:
对于浅复制,意味着字典的内容不是对值的拷贝,而是创建了新的引用:
>>> a = {1: [1,2,3]}
>>> b = a.copy()
>>> print a, b
>>> ({1: [1, 2, 3]}, {1: [1, 2, 3]})
>>> a[1].append(4)
>>> print a, b
>>> ({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})
相对的,深复制(deep copy)会复制所有的内容,包括值:
>>> c = copy.deepcopy(a)
>>> print a, c
>>> ({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]})
>>> a[1].append(5)
>>> print a, c
>>> ({1: [1, 2, 3, 4, 5]}, {1: [1, 2, 3, 4]})
总的来说:
1.a = b
:引用复制,使a和b指向相同的对象:
a ---,
v
{1: L}
^ |
b ---' '----> [1,2,3]
2.a = b.copy()
:浅复制,a和b会成为两个不同的对象,但它们的内容会共享相同的引用:
a ---> {1: L}
|
>---> [1,2,3]
|
b ---> {1: M}
3.a = copy.deepcopy(b)
:深复制,a、b的结构和内容都完全隔离开了:
a ---> {1: L}
‘-----> [1,2,3]
b ---> {1: M}
‘-----> [1,2,3]