22

I'm creating a dictionary structure that is several levels deep. I'm trying to do something like the following:

dict = {}
dict['a']['b'] = True

At the moment the above fails because key 'a' does not exist. At the moment I have to check at every level of nesting and manually insert an empty dictionary. Is there some type of syntactic sugar to be able to do something like the above can produce:

{'a': {'b': True}}

Without having to create an empty dictionary at each level of nesting?

deltanovember
  • 42,611
  • 64
  • 162
  • 244

4 Answers4

35

As others have said, use defaultdict. This is the idiom I prefer for arbitrarily-deep nesting of dictionaries:

def nested_dict():
    return collections.defaultdict(nested_dict)

d = nested_dict()
d[1][2][3] = 'Hello, dictionary!'
print(d[1][2][3]) # Prints Hello, dictionary!

This also makes checking whether an element exists a little nicer, too, since you may no longer need to use get:

if not d[2][3][4][5]:
    print('That element is empty!')

This has been edited to use a def rather than a lambda for pep8 compliance. The original lambda form looked like this below, which has the drawback of being called <lambda> everywhere instead of getting a proper function name.

>>> nested_dict = lambda: collections.defaultdict(nested_dict)
>>> d = nested_dict()
>>> d[1][2][3]
defaultdict(<function <lambda> at 0x037E7540>, {})
Craig McQueen
  • 41,871
  • 30
  • 130
  • 181
Henry Keiter
  • 16,863
  • 7
  • 51
  • 80
2

Use defaultdict.

Python: defaultdict of defaultdict?

Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
0

Or you can do this, since dict() function can handle **kwargs:

http://docs.python.org/2/library/functions.html#func-dict

print dict(a=dict(b=True))
# {'a': {'b' : True}}
Peter Varo
  • 11,726
  • 7
  • 55
  • 77
0

If the depth of your data structure is fixed (that is, you know in advance that you need mydict[a][b][c] but not mydict[a][b][c][d]), you can build a nested defaultdict structure using lambda expressions to create the inner structures:

two_level = defaultdict(dict)
three_level = defaultdict(lambda: defaultdict(dict))
four_level = defaultdict(lamda: defaultdict(lambda: defaultdict(dict)))
Blckknght
  • 100,903
  • 11
  • 120
  • 169