I dislike giving ready made answers - but I think it would take much more time to explain it in English -
The basic idea to fetch objects the way numpy does is to customize the __getitem__ method - comma separated values are presented to the method as tuples - you them just use the values in the tuple as indexes to your nested dictionaries in sequence.
Beyond that, Python made easy to create fully functional dict equivalentes with the collections.abc classes: if you implement a minimal set of methods when inhetiring from collections[.abc].MutableMapping, all dictionary behavior is emulated - (__getitem__, __setitem__, __delitem__, __iter__, __len__) - Then, it is just a matter of proper iterating through the key components, and create new, empty, regular dictionaries to store the needed values.
try:
from collections import MutableMapping
except ImportError:
# Python3 compatible import
from collections.abc import MutableMapping
class NestedDict(MutableMapping):
def __init__(self, *args, **kw):
self.data = dict(*args, **kw)
def get_last_key_levels(self, key, create=False):
if not isinstance(key, tuple):
key = (key,)
current_data = self.data
for subkey in key:
previous = current_data
current_data = current_data[subkey] if not create else current_data.setdefault(subkey, {})
return previous, current_data, subkey
def __getitem__(self, key):
previous, current_data, lastkey = self.get_last_key_levels(key)
return current_data
def __setitem__(self, key, value):
previous, current_data, lastkey = self.get_last_key_levels(key, True)
previous[lastkey] = value
def __delitem__(self, key):
previous, current_data, lastkey = self.get_last_key_levels(key)
del previous[lastkey]
def __iter__(self):
return iter(self.data)
def __len__(self):
return len(self.data)
def __repr__(self):
return "NestedDict({})".format(repr(self.data))
And you are set to go:
>>> from nesteddict import NestedDict
>>> x = NestedDict(a={})
NestedDict({'a': {}})
>>> x["a", "b"] = 10
>>> x
NestedDict({'a': {'b': 10}})
>>> x["a", "c", "e"] = 25
>>> x
NestedDict({'a': {'c': {'e': 25}, 'b': 10}})
>>> x["a", "c", "e"]
25
>>>
Please note that this is a high-level implementation, which will just work, but you will have nowhere near the optimization level you get on NumPy with this - to the contrary. If you will need to perform fast data operations in these objects, you maybe could check "cython" - or resort to your idea of transposing the dict keys to nuemric keys and use NumPy (that idea could still pick some ideas from this answer)