[Tutor] Dictionary of dictionaries issue

A.T.Hofkamp a.t.hofkamp at tue.nl
Thu Nov 13 16:01:14 CET 2008


Pablo Englebienne wrote:
> Hi, I'm trying to work with a dictionary of dictionaries and I'm having 
> trouble accessing a specific element of it:
> 
> $ python
> Python 2.6 (trunk:66714:66715M, Oct  1 2008, 18:36:04)
> [GCC 4.0.1 (Apple Computer, Inc. build 5370)] on darwin
> Type "help", "copyright", "credits" or "license" for more information.
>  >>> r = ('a','b','c')
>  >>> c = (1,2,3)
>  >>> d = dict.fromkeys(r,dict.fromkeys(c))
>  >>> d

This does

d0 = dict.fromkeys(c)
d  = dict.fromkeys(r, d0)


> {'a': {1: None, 2: None, 3: None}, 'c': {1: None, 2: None, 3: None}, 
> 'b': {1: None, 2: None, 3: None}}
>  >>> d['a'][1]=0
>  >>> d
> {'a': {1: 0, 2: None, 3: None}, 'c': {1: 0, 2: None, 3: None}, 'b': {1: 
> 0, 2: None, 3: None}}
>  >>> import copy
> 
> As you can see, attempting to assign a specific member, d['a'][1] 
> updates all values in d[*][1], not what I intended.

The d0 value is shared between all keys of d. As a result, you get the 
behaviour you noticed.
(ie there is only 1 dict-value, it gets printed 3 times when you print 'd')

> I thought the solution could be in using copy.deepcopy, but I might not 
> be using it right:
> 
>  >>> d2 = dict.fromkeys(r,copy.deepcopy(dict.fromkeys(c)))

Here you do

d0 = dict.fromkeys(c)
d1 = copy.deepcopy(d0)
d2 = dict.fromkeys(r, d1)

d0 and d1 are completely seperate due to the deepcopy(), but the last line 
still uses the same d1 value for all its keys, as in your first attempt. for 
this reason, the problem does not disappear.


> Any suggestions/pointers would be appreciated!

To solve this, you need to construct a fresh value for each key.

You can do this with an iterator and a dictionary constructor:

 >>> c = (1,2,3)
 >>> r = ('a','b','c')
 >>> d3 = dict(( (rv, dict.fromkeys(c)) for rv in r ))

d3 is created by constructing a dict from a list of tuples (key, val), where 
the key rv is from your 'r' tuple, and val is constructed anew each time from 'c'.

 >>> d3
{'a': {1: None, 2: None, 3: None}, 'c': {1: None, 2: None, 3: None}, 'b': {1: 
None, 2: None, 3: None}}
 >>> d3['a'][1]=0
 >>> d3
{'a': {1: 0, 2: None, 3: None}, 'c': {1: None, 2: None, 3: None}, 'b': {1: 
None, 2: None, 3: None}}

Sincerely,
Albert



More information about the Tutor mailing list