2

I have a document like this:

>>> k = {'finance_pl':{'S':{'2008':45,'2009':34}}}

Normal way to access is:

>>> k['finance_pl']['S']
{'2008': 45, '2009': 34}

But, in my case the end user will give me input as finance_pl.S

I can split this and access the dictionary like this:

>>> doc_list = doc.split('.')
>>> k[doc_list[0]][doc_list[1]]
{'2008': 45, '2009': 34}

But, I don't want to do this, since the dictionary structure may change the and user can give something like this finance_pl.new.S instead of k['finance_pl']['S'] or k[doc_list[0]][doc_list[1]].

I need something to apply the users input directly (Ex: if input is finance_pl.new.S, I should be able to apply this .split('.') method to the users input and apply directly).

What is the elegant way to do that ?

perror
  • 7,071
  • 16
  • 58
  • 85
John Prawyn
  • 1,423
  • 3
  • 19
  • 28
  • 1
    Not sure whether I understood the question correctly, i.e. whether there's more to it, but I think you should look at this [related question](http://stackoverflow.com/q/12414821/1639625) – tobias_k Jul 22 '13 at 12:19
  • 1
    I answered a similar question [here](http://stackoverflow.com/questions/14923465/python-how-to-return-a-default-value/14923509#14923509) I think it will help you. Also, see [Jon's Answer](http://stackoverflow.com/a/17787473/1561176) Which is how I would have answered your question. – Inbar Rose Jul 22 '13 at 12:33
  • Yes, @tobias_k I need something like this only. – John Prawyn Jul 22 '13 at 12:47

4 Answers4

5

I'd simply loop over all the parts:

def getter(somedict, key):
    parts = key.split(".")
    for part in parts:
        somedict = somedict[part]
    return somedict

after which we have

>>> getter(k, "finance_pl.S")
{'2008': 45, '2009': 34}

or

>>> getter({"a": {"b": {"c": "d"}}}, "a")
{'b': {'c': 'd'}}
>>> getter({"a": {"b": {"c": "d"}}}, "a.b.c")
'd'
DSM
  • 342,061
  • 65
  • 592
  • 494
2

You could go for something like:

k = {'finance_pl':{'S':{'2008':45,'2009':34}}}
print reduce(dict.__getitem__, 'finance_pl.S.2009'.split('.'), k)
# 34

If you're using Python 3.x, you'll need a from functools import reduce in there...

Jon Clements
  • 138,671
  • 33
  • 247
  • 280
1
userkey = 'finance_pl.new.S'
for key in userkey.split('.'):
    k = k[key]
# the final value of k is the one you want

So basically just iterate on every subkey and retrieve the inner dictionary until you're out of subkeys

dnaq
  • 2,104
  • 1
  • 14
  • 24
1
>>> k = {'finance_pl':{'S':{'2008':45,'2009':34}}}
>>> ui = 'finance_pl.S'
>>> def getter(adict, key):
...     return reduce(dict.get, key.split('.'), adict)
... 
>>> getter(k, ui)
{'2008': 45, '2009': 34}
>>> 
zhangyangyu
  • 8,520
  • 2
  • 33
  • 43