Skip to content

Instantly share code, notes, and snippets.

@cwells
Last active May 25, 2018 20:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cwells/c2ce19f730ca9f540d7280201f2e3240 to your computer and use it in GitHub Desktop.
Save cwells/c2ce19f730ca9f540d7280201f2e3240 to your computer and use it in GitHub Desktop.
def dig(d, keys, *args):
"""Locate a value in a nested dictionary.
Args:
d (dict): the dictionary
keys (list): list of keys to index the dictionary with
default (value|callable): value or callable to return in case of missing key
Returns:
Value at `d[k0][k1][...]` if all keys are present
Value of `default` if missing key encountered
Raises:
KeyError: if missing key (unless `default` provided)
Accepts a nested dictionary, a sequence of keys, and an optional
default return value in case of an exception.
Given the dictionary `dict` and the keys `[k1, k2, k3]`, attempts
to return the value located at dict[k1][k2][k3].
Unless the `default` argument is provided, a missing key will cause
a KeyError exception to be raised.
If the `default` argument is provided, it will be the return value
in case of a KeyError (rather than the exception). The value for
`default` can be either a plain value or a function. If it is a value,
it is returned as-is. If it is a function, the function is called
with the last found value and the missing key as arguments and the
function's return value is returned to the caller.
d = { 'a': { 'b': { 'c': { 'd': True } } } }
dig(d, ['a', 'b', 'c', 'd']) # True
dig(d, ['a', 'c']) # raises KeyError
dig(d, ['a', 'c', 'd'], None) # None
dig(d, ['a', 'b', 'd'], lambda v: v) # d['a']['b'] == {'c': {'d': True}}
"""
def error(d, k): raise
default = args[0] if args else error
try:
value = d[keys[0]]
except KeyError:
return default(d, keys[0]) if callable(default) else default
return dig(value, keys[1:], default) if len(keys) > 1 else value
d = { 'a': { 'b': { 'c': { 'd': True } } } }
dig(d, ['a', 'b', 'c', 'd']) # True
dig(d, ['a', 'e']) # raises KeyError
dig(d, ['a', 'b', 'e'], None) # None
dig(d, ['a', 'b', 'e'], lambda d, k: d) # d['a']['b'] == {'c': {'d': True}}
dig(d, ['a', 'b', 'e'], lambda d, k: d).setdefault('e', "Hello, world.")
dig(d, ['a', 'b', 'e']) # "Hello, world."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment