Working with copies of a dictionary

Duncan Smith buzzard at urubu.freeserve.co.uk
Fri Dec 12 19:41:48 EST 2003


"Tobias Pfeiffer" <me at privacy.net> wrote in message
news:brdk8u$29hpe$1 at ID-162581.news.uni-berlin.de...
> Hi!
>
> Damnit, am I angry! Please look at the following example:
>
> class bla:
> def __init__(self):
> self.ho = {'a': ['b'], 'c': ['b', 'e', 'f', 'd'], 'b':
> ['a', 'e', 'f', 'c'], 'e': ['b', 'c', 'g', 'h'], 'd': ['c'], 'g': ['e',
> 'h'], 'f': ['b', 'c'], 'h': ['e', 'g']} # shall be an adjacence list of
> a graph...
> self.oha = [('a', 'b'), ('b', 'c'), ('b', 'e'), ('b', 'f'),
> ('c', 'd'), ('c', 'e'), ('c', 'f'), ('e', 'g'), ('e', 'h'), ('g', 'h')]
> def do_stuff(self):
> next = self.ho.copy() # HERE!!!
>
> edges = self.oha[:]
>
> next['c'].remove('e')
> next['g'].remove('h')
> del next['b']
> edges.pop(0)
> edges.pop(3)
> edges.pop(6)
>
> f = bla()
> print f.ho
> print f.oha
>
> OK, so the two last lines, what surprising thing give me exactly the
> long dictionary I defined in __init__.
>
> f.do_stuff()
>
> Now you see that I do nothing with the self.* thingies themselves. So
> why in hell do the following two lines give me a different output???
>
> print f.ho
> print f.oha
>
> f.oha hasn't changed, but f.ho now lacks the two elements I deleted
> from next with the remove() call, while the 'b' array is still there.
> Now can anyone please explain me why do_stuff() ha changed the
> attributes of the class?? Even the following:
>
> next = {}
> for v, e in self.ho.items():
> next[v] = e
>
> , where one can easily see that next does not even have the slightest
> connection to f.ho, changes it!! I am completely desparate, because I
> would just like to work with the copy of that dictionary, without
> deleting the proper one. How can I do such a thing?
>
> Thanks in Advance
> Tobias
>
> --
> please send any mail to botedesschattens(at)web(dot)de

Not even the slightest connection is not quite right.

>>> adict = {'a':[1,2,3], 'b':[3,4,5]}
>>> anotherdict = adict.copy()
>>> id(adict['a'])
10410608
>>> id(anotherdict['a'])
10410608
>>>

adict['a'] and anotherdict['a'] reference the same list.  Try a deep copy.

>>> import copy
>>> a_third_dict = copy.deepcopy(adict)
>>> a_third_dict
{'a': [1, 2, 3], 'b': [3, 4, 5]}
>>> id(adict3['a'])
10411984

Duncan






More information about the Python-list mailing list