1

I'm making simple use case of my problem, here its is:

dic =  {'a': 1, 'b': {'c': 2}}

Now i want to have a method which operates on this dictionary, fetch values based on the key.

def get_value(dic, key):
     return dic[key]

At different places this generic method will be called to fetch the values.

get_value(dic, 'a') will work.

Is it be possible to get the value 2 (dic['b']['c']) in more generic way.

navyad
  • 3,752
  • 7
  • 47
  • 88

1 Answers1

6

Using unbound method dict.get (or dict.__getitem__) and reduce:

>>> # from functools import reduce  # Python 3.x only
>>> reduce(dict.get, ['b', 'c'], {'a': 1, 'b': {'c': 2}})
2

>>> reduce(lambda d, key: d[key], ['b', 'c'], {'a': 1, 'b': {'c': 2}})
2

UPDATE

If you use dict.get and try to access non-existing key, it could hide KeyError by returning None:

>>> reduce(dict.get, ['x', 'c'], OrderedDict({'a': 1, 'b': {'c': 2}}))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: descriptor 'get' requires a 'dict' object but received a 'NoneType'

To prevent that, use dict.__getitem__:

>>> reduce(dict.__getitem__, ['x', 'c'], OrderedDict({'a': 1, 'b': {'c': 2}}))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'x'
falsetru
  • 357,413
  • 63
  • 732
  • 636