Working with copies of a dictionary

T

Tobias Pfeiffer

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
 
D

Duncan Smith

Tobias Pfeiffer said:
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

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
 
D

Duncan Smith

[snip]
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

Of course I shouldn't edit output once I've pasted it. That should be,
10411984
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,477
Latest member
ColumbusMa

Latest Threads

Top