[python] Accessing value inside nested dictionaries

I am new to python and need help in solving an issue:

I have a dictionary like

tmpDict = {'ONE':{'TWO':{'THREE':10}}}

Do we have any other way to access THREE's value other than doing

tmpDict['ONE']['TWO']['THREE']

?

This question is related to python dictionary

The answer is


No, those are nested dictionaries, so that is the only real way (you could use get() but it's the same thing in essence). However, there is an alternative. Instead of having nested dictionaries, you can use a tuple as a key instead:

tempDict = {("ONE", "TWO", "THREE"): 10}
tempDict["ONE", "TWO", "THREE"]

This does have a disadvantage, there is no (easy and fast) way of getting all of the elements of "TWO" for example, but if that doesn't matter, this could be a good solution.


As always in python, there are of course several ways to do it, but there is one obvious way to do it.

tmpdict["ONE"]["TWO"]["THREE"] is the obvious way to do it.

When that does not fit well with your algorithm, that may be a hint that your structure is not the best for the problem.

If you just want to just save you repetative typing, you can of course alias a subset of the dict:

>>> two_dict = tmpdict['ONE']['TWO'] # now you can just write two_dict for tmpdict['ONE']['TWO']
>>> two_dict["spam"] = 23
>>> tmpdict
{'ONE': {'TWO': {'THREE': 10, 'spam': 23}}}

My implementation:

def get_nested(data, *args):
    if args and data:
        element  = args[0]
        if element:
            value = data.get(element)
            return value if len(args) == 1 else get_nested(value, *args[1:])

Example usage:

>>> dct={"foo":{"bar":{"one":1, "two":2}, "misc":[1,2,3]}, "foo2":123}
>>> get_nested(dct, "foo", "bar", "one")
1
>>> get_nested(dct, "foo", "bar", "two")
2
>>> get_nested(dct, "foo", "misc")
[1, 2, 3]
>>> get_nested(dct, "foo", "missing")
>>>

There are no exceptions raised in case a key is missing, None value is returned in that case.


The answer was given already by either Sivasubramaniam Arunachalam or ch3ka.

I am just adding a performances view of the answer.

dicttest={}
dicttest['ligne1']={'ligne1.1':'test','ligne1.2':'test8'}
%timeit dicttest['ligne1']['ligne1.1']
%timeit dicttest.get('ligne1').get('ligne1.1')

gives us :

112 ns ± 29.7 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

235 ns ± 9.82 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)