3

Say I want to write a function which will return an arbitrary value from a dict, like: mydict['foo']['bar']['baz'], or return an empty string if it doesn't. However, I don't know if mydict['foo'] will necessarily exist, let alone mydict['foo']['bar']['baz'].

I'd like to do something like:

safe_nested(dict, element):
  try:
    return dict[element]
  except KeyError:
    return ''

But I don't know how to approach writing code that will accept the lookup path in the function. I started going down the route of accepting a period-separated string (like foo.bar.baz) so this function could recursively try to get the next sub-dict, but this didn't feel very Pythonic. I'm wondering if there's a way to pass in both the dict (mydict) and the sub-structure I'm interested in (['foo']['bar']['baz']), and have the function try to access this or return an empty string if it encounters a KeyError.

Am I going about this in the right way?

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
Christopher Armstrong
  • 7,907
  • 2
  • 26
  • 28

2 Answers2

3

You should use the standard defaultdict: https://docs.python.org/2/library/collections.html#collections.defaultdict

For how to nest them, see: defaultdict of defaultdict, nested or Multiple levels of 'collection.defaultdict' in Python

I think this does what you want:

from collections import defaultdict
mydict = defaultdict(lambda: defaultdict(lambda: defaultdict(str)))
Community
  • 1
  • 1
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • I believe `defaultdict` is not a solution to the OP's problem. He already has a nested `dict` structure. – thefourtheye Jan 20 '15 at 08:19
  • @thefourtheye: I've updated my answer with specific working code for the OP's problem. – John Zwinck Jan 20 '15 at 08:24
  • I guess that is not going to help OP I guess. I think he has a dictionary where the keys have dictionaries as values and those dictionaries have keys which have values as dictionaries and so on. Now, he wants to get the actual value from the dictionary from a sequence of keys if the hierarchy of keys exist otherwise an empty string. – thefourtheye Jan 20 '15 at 08:37
0

You might also want to check out addict.

>>> from addict import Dict
>>> addicted = Dict()
>>> addicted.a = 2
>>> addicted.b.c.d.e
{}
>>> addicted
{'a': 2, 'b': {'c': {'d': {'e': {}}}}}

It returns an empty Dict, not an empty string, but apart from that it looks like it does what you ask for in the question.

Håken Lid
  • 22,318
  • 9
  • 52
  • 67