Onkar N Mahajan Onkar N Mahajan - 1 month ago 6
Python Question

Strange behaviour of delete dictionary operation on nested dictionary

#!/usr/bin/python
import numpy as np

td={}
d = {}
for col in ['foo','bar','baz']:
for row in ['a','b','c','d']:
td.setdefault(row, np.random.randn())
d.setdefault(col, td)

print d
del d['foo']['c']
print d


output:

{'baz': {'a': -1.6340274257732716, 'c': 0.6674016962534858, 'b': 2.0410088421902652, 'd': -1.2602923734811284}, 'foo': {'a': -1.6340274257732716, 'c': 0.6674016962534858, 'b': 2.0410088421902652, 'd': -1.2602923734811284}, 'bar': {'a': -1.6340274257732716, 'c': 0.6674016962534858, 'b': 2.0410088421902652, 'd': -1.2602923734811284}}
{'baz': {'a': -1.6340274257732716, 'b': 2.0410088421902652, 'd': -1.2602923734811284}, 'foo': {'a': -1.6340274257732716, 'b': 2.0410088421902652, 'd': -1.2602923734811284}, 'bar': {'a': -1.6340274257732716, 'b': 2.0410088421902652, 'd': -1.2602923734811284}}


Intention here is to delete only
d['foo']['c]
, but all the
'c'
's are getting deleted across
'foo', 'bar', 'baz'
.. Not sure if this has been already answered on this forum, if yes please point me to that answer.

Answer

You are setting each value in d to reference the same copy of td. If you want the copies to be distinct, you'll need to create more than one td dictionary.

Try this:

#!/usr/bin/python
import numpy as np

d = {}
for col in ['foo','bar','baz']:
    td = {}
    for row in ['a','b','c','d']:
        td.setdefault(row, np.random.randn())
    d.setdefault(col, td)

print d
del d['foo']['c']
print d