user1496984
user1496984

Reputation: 11575

Python - Access hierarchical dict element from list of keys

Let's say I have a regular "dict-of-dicts" as follows:

d = {}
d['a'] = {}
d['a']['b'] = 3

I can of course access the element using d['a']['b'].

In my case, I have a recursive application, in which I keep the current state as a list of keys. So I would have

my_key = ['a', 'b']

How do I access the value 3, using my_key? The issue, of course, is that my_key can be arbitrarily long (deep).

I realize I can write another traversal function or so, but it seems like there should be a straightforward way of doing so. Any ideas?

Upvotes: 4

Views: 3350

Answers (2)

CristiFati
CristiFati

Reputation: 41137

Currently dictionary keys can only be hashable types, list (ListType) is not one of them, so if you try to specify a list as a dictionary key:

{}[[]]

you'll get:

TypeError: unhashable type: 'list'`.

You could enhance the current dictionary, allowing to specify a list as a key, and iterate over the list on inner objects. Here's the code (note that it only takes care of the get/read part):

from types import DictType, ListType

class EnhancedDictType(DictType):
    def __getitem__(self, key):
        if key and isinstance(key, ListType):
            new_obj = self
            for item in key:
                new_obj = new_obj[item]
            return new_obj
        else:
            return super(EnhancedDictType, self).__getitem__(key)

dict = EnhancedDictType

Here's also some test code:

d = dict()
d[1] = dict()
d[1][2] = dict({3: 4})
d[(1, 2, 3)] = 5
print d
print d[1]
print d[1][2]
print d[[1, 2]]
print d[[1 ,2, 3]]
print d[(1, 2, 3)]

Upvotes: 1

Kevin
Kevin

Reputation: 76234

You could use reduce to iteratively index each layer of dict with a different key:

>>> from functools import reduce #only necessary in 3.X
>>> d = {}
>>> d['a'] = {} #I'm assuming this is what you meant to type
>>> d['a']['b'] = 3
>>> keys = ("a", "b")
>>> reduce(dict.get, keys, d)
3

Upvotes: 9

Related Questions