python - Programmatically accessing arbitrarily deeply-nested values in a dictionary -
this question has answer here:
i'm working on python script i'm given lists of strings of format: ['key1', 'key2', 'key2.key21.key211', 'key2.key22', 'key3']
.
each value in list corresponds entry in dictionary, , entries structured 'key2.key21.key211'
, correspond (in example), key 'key211'
nested within 'key21'
, nested inside 'key2'
.
the above list corresponds dictionary:
x = { 'key1' : 'value1', 'key2' : { 'key21' : { 'key211': 'value211' }, 'key22' : 'value22' }, 'key3' : 'value3' }
the names not regular key(n)+
; can of form food.vegetables.potato
, example. guarantees have key names themselves, in dictionary, not contain .
character, , dictionary contains entries referenced in original list.
my question is, given such list of strings, how programmatically access corresponding entries in dictionary? can think of solution using eval()
, 1 using traversal/search, want avoid calls eval()
, , impression traversal comparisons slow (since dict
s aren't search trees), , entail lot of nasty exception handling.
one approach write function access keys in nested dicts.
def deep_access(x,keylist): val = x key in keylist: val = val[key] return val s = 'key2.key21.key211' print deep_access(x,s.split('.'))
result:
value211
another approach, if want use similar syntax normal dictionary access subclass dict
, override __getitem__
allow nested access when tuple of keys provided:
class nesteddict(dict): def __getitem__(self,keytuple): # if key not tuple access normal if not isinstance(keytuple, tuple): return super(nesteddict,self).__getitem__(keytuple) d = self key in keytuple: d = d[key] return d >>> nd = nesteddict(x) >>> nd['key2'] {'key22': 'value22', 'key21': {'key211': 'value211'}} >>> nd['key2','key22'] 'value22' >>> nd['key2','key21'] {'key211': 'value211'} >>> nd['key2','key21','key211'] 'value211'
you can implement __setitem__
, __delitem__
needed.
Comments
Post a Comment