Accessing values nested within dictionaries
Solution 1:
You can use something like this:
>>> def lookup(dic, key, *keys):
... if keys:
... return lookup(dic.get(key, {}), *keys)
... return dic.get(key)
...
>>> d = {'a':{'b':{'c':5}}}
>>> print lookup(d, 'a', 'b', 'c')
5
>>> print lookup(d, 'a', 'c')
None
Additionally, if you don't want to define your search keys as individual parameters, you can just pass them in as a list like this:
>>> print lookup(d, *['a', 'b', 'c'])
5
>>> print lookup(d, *['a', 'c'])
None
Solution 2:
bill_to = transactions['Transaction Details']['Bill To']
actually works. transactions['Transaction Details']
is an expression denoting a dict
, so you can do lookup in it. For practical programs, I would prefer an OO approach to nested dicts, though. collections.namedtuple
is particularly useful for quickly setting up a bunch of classes that only contain data (and no behavior of their own).
There's one caveat: in some settings, you might want to catch KeyError
when doing lookups, and in this setting, that works too, it's hard to tell which dictionary lookup failed:
try:
bill_to = transactions['Transaction Details']['Bill To']
except KeyError:
# which of the two lookups failed?
# we don't know unless we inspect the exception;
# but it's easier to do the lookup and error handling in two steps
Solution 3:
Following is another way of accessing nested dictionaries
>>> dbo={'m':{'d':{'v':{'version':1}}}}
>>> name='m__d__v__version' # it'll refer to 'dbo['m']['d']['v']['version']', '__' is the separator
>>> version = reduce(dict.get, name.split('__'), dbo)
>>> print version
1
>>>
Here, variable 'name' refers to 'dbo['m']['d']['v']['version']', which seems much shorter and neat.
This method will not throw KeyError. If a key is not found then you'll get 'None'.
Ref.: http://code.activestate.com/recipes/475156-using-reduce-to-access-deeply-nested-dictionaries/