![]() |
is dict.copy() a deep copy or a shallow copy
Entering the following in the Python shell yields
>>> help(dict.copy) Help on method_descriptor: copy(...) D.copy() -> a shallow copy of D >>> Ok, I thought a dictionary copy is a shallow copy. Not knowing exactly what that meant I went to http://en.wikipedia.org/wiki/Deep_copy where I could read "...a deep copy is copy that contains the complete encapsulated data of the original object, allowing it to be used independently of the original object. In contrast, a shallow copy is a copy that may be associated to data shared by the original and the copy" Going back to Python shell I tested the following >>> D={'Python': 'good', 'Basic': 'simple'} >>> E=D.copy() >>> E {'Python': 'good', 'Basic': 'simple'} >>> D['Basic']='oh my' >>> D {'Python': 'good', 'Basic': 'oh my'} >>> E {'Python': 'good', 'Basic': 'simple'} >>> Hmm, this looks like a deep copy to me?? I also tried >>> D={'Python': 'good', 'Basic': 'simple'} >>> E=D >>> E {'Python': 'good', 'Basic': 'simple'} >>> E['Basic']='oh my' >>> E {'Python': 'good', 'Basic': 'oh my'} >>> D {'Python': 'good', 'Basic': 'oh my'} >>> which looks like a shallow copy to me?? So my hypothesis is that E=D is a shallow copy while E=D.copy() is a deep copy. So is the documentation wrong when they claim that D.copy() returns a shallow copy of D, or did I misunderstand the difference between a deep and shallow copy? Thanks |
Re: is dict.copy() a deep copy or a shallow copy
"Alex" <lidenalex@yahoo.se> wrote in
news:1125863497.723200.178620@z14g2000cwz.googlegr oups.com: >>>> D={'Python': 'good', 'Basic': 'simple'} >>>> E=D.copy() >>>> E > {'Python': 'good', 'Basic': 'simple'} >>>> D['Basic']='oh my' >>>> D > {'Python': 'good', 'Basic': 'oh my'} >>>> E > {'Python': 'good', 'Basic': 'simple'} >>>> > > Hmm, this looks like a deep copy to me?? I also tried > It is shallow, but strings are immutable so the difference is fairly moot. >>>> D={'Python': 'good', 'Basic': 'simple'} >>>> E=D >>>> E > {'Python': 'good', 'Basic': 'simple'} >>>> E['Basic']='oh my' >>>> E > {'Python': 'good', 'Basic': 'oh my'} >>>> D > {'Python': 'good', 'Basic': 'oh my'} >>>> > Here, E and D are different names for the same object. There is no copy. > which looks like a shallow copy to me?? So my hypothesis is that > E=D is a shallow copy while E=D.copy() is a deep copy. > > So is the documentation wrong when they claim that D.copy() > returns a shallow copy of D, or did I misunderstand the > difference between a deep and shallow copy? Sort of, some examples: Here d1 and d2 are copies. They can be independently changed to refer to different objects: >>> d1={'a':1,'b':2} >>> d2=d1.copy() >>> d1['a']=3 >>> d2['b']=4 >>> d1 {'a': 3, 'b': 2} >>> d2 {'a': 1, 'b': 4} Again, d3 and d4 are copies, but instead of changing the objects they refer to, we change the contents of the objects they refer to: >>> d3={'c':[3],'d':[4]} >>> d4=d3.copy() >>> d3['c'][0]=5 >>> d4['d'][0]=6 >>> d3 {'c': [5], 'd': [6]} >>> d4 {'c': [5], 'd': [6]} Both cases are shallow copies. In a deep copy, altering the contents of d3['c'] would have no impact on the contents of d4['c']. max |
Re: is dict.copy() a deep copy or a shallow copy
Thanks max,
Now it's much clearer. I made the following experiment >>>#1 >>> D={'a':1, 'b':2} >>> D {'a': 1, 'b': 2} >>> E=D.copy() >>> E {'a': 1, 'b': 2} >>> D['a']=3 >>> D {'a': 3, 'b': 2} >>> E {'a': 1, 'b': 2} >>>#2 >>> D={'a':[1,3], 'b':[2,4]} >>> D {'a': [1, 3], 'b': [2, 4]} >>> E=D.copy() >>> E {'a': [1, 3], 'b': [2, 4]} >>> D['a'][0]=9 >>> D {'a': [9, 3], 'b': [2, 4]} >>> E {'a': [9, 3], 'b': [2, 4]} >>>#3 >>> import copy >>> F=copy.deepcopy(D) >>> D {'a': [9, 3], 'b': [2, 4]} >>> F {'a': [9, 3], 'b': [2, 4]} >>> D['a'][0]=7 >>> D {'a': [7, 3], 'b': [2, 4]} >>> F {'a': [9, 3], 'b': [2, 4]} >>> A shallow copy of an object is a copy of the first-level data members and if one of the members is a pointer, then only the pointer value is copied, not the structure pointed to by the pointer. The original object and its shallow copy share the memory space occupied by these structures. A deep copy of an object is a copy of everything (including the structures pointe to by the pointers). The original object and its deep copy do not share any memory space. In #1 no pointers are involved so changing a value affects only D but not E. In #2 D['a'] and E['a'] are pointers that both point to the same memory space. Changing that memory space doesn't change the pointers themsleves. In #3 a deepcopy makes sure that a copy is made not just of the pointers but also of the things pointed to. So the lesson to be learned is that if you make a copy of a dictionary whose values are pointers to other structures then a deepcopy prevents a coupling between a the original and the copy. Alex |
| All times are GMT. The time now is 01:59 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.