What's the best way to initialize a dict of dicts in Python?

mike picture mike · Mar 16, 2009 · Viewed 91.2k times · Source

A lot of times in Perl, I'll do something like this:

$myhash{foo}{bar}{baz} = 1

How would I translate this to Python? So far I have:

if not 'foo' in myhash:
    myhash['foo'] = {}
if not 'bar' in myhash['foo']:
    myhash['foo']['bar'] = {}
myhash['foo']['bar']['baz'] = 1

Is there a better way?

Answer

John Fouhy picture John Fouhy · Mar 16, 2009

If the amount of nesting you need is fixed, collections.defaultdict is wonderful.

e.g. nesting two deep:

myhash = collections.defaultdict(dict)
myhash[1][2] = 3
myhash[1][3] = 13
myhash[2][4] = 9

If you want to go another level of nesting, you'll need to do something like:

myhash = collections.defaultdict(lambda : collections.defaultdict(dict))
myhash[1][2][3] = 4
myhash[1][3][3] = 5
myhash[1][2]['test'] = 6

edit: MizardX points out that we can get full genericity with a simple function:

import collections
def makehash():
    return collections.defaultdict(makehash)

Now we can do:

myhash = makehash()
myhash[1][2] = 4
myhash[1][3] = 8
myhash[2][5][8] = 17
# etc