[Tutor] Dictionary of dictionaries issue

Kent Johnson kent37 at tds.net
Thu Nov 13 16:24:27 CET 2008


On Thu, Nov 13, 2008 at 8:11 AM, Pablo Englebienne
<pablo.englebienne at gmail.com> 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
> {'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.
>
> I thought the solution could be in using copy.deepcopy,

The problem is, whether you use deepcopy() or not, the values of d are
all the same - every key of d refers to the same value, which is your
nested dict. So when you change it in one place, it changes
everywhere.

dict.fromkeys() is not going to work for this, because it always will
give the same value for each key. You need to create a new dict for
each value.

One solution is just to use a loop, creating a new value dict each
time through the loop:
In [3]: r = ('a','b','c')

In [4]: c = (1,2,3)

In [5]: d = {}

In [6]: for k in r:
   ...:     d[k] = dict.fromkeys(c)

In [7]: d
Out[7]:
{'a': {1: None, 2: None, 3: None},
 'b': {1: None, 2: None, 3: None},
 'c': {1: None, 2: None, 3: None}}

In [8]: d['a'][1] = 0

In [9]: d
Out[9]:
{'a': {1: 0, 2: None, 3: None},
 'b': {1: None, 2: None, 3: None},
 'c': {1: None, 2: None, 3: None}}

You could also create a sequence of (key, value) pairs as Albert suggests.

Kent


More information about the Tutor mailing list