Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested, infinite dictionary in python

I want set the keys and values ​​in the dictionary. Here is an example of what I do.

class NestedDict(dict):
    def __getitem__(self, key):
        if key in self: return self.get(key)
        return self.setdefault(key, NestedDict())

>>> c = NestedDict()
>>> c
{}
>>> c['a']['b'] = 'test'
>>> c['a']['c'] = 2
>>> c
{'a': {'c': 2, 'b': 'test'}}
>>> c['a']['c'] += 1
>>> c
{'a': {'c': 3, 'b': 'test'}}
>>> c['a']['d'] += 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +=: 'NestedDict' and 'int'

Any ideas how to solve this problem? I want be able to use += and -=. Of course if value doesn't exist then += 1 is these same as = 1. Maybe there's a better solution?

Thanks.

like image 317
eshlox Avatar asked May 16 '26 05:05

eshlox


2 Answers

Since d is non existent in c['a'], what kind of behaviour do you expect when you try to add 1 to it? It will first call __getitem__, not find the key and then return a NestedDict which doesn't support in place addition with an int.

On a side note, It looks to me as though you're trying to implement a dictionary with a "default" value. I would use the defaultdict class available in the collections module like so

from collections import defaultdict

def create_nested_dict():
   return defaultdict(create_nested_dict)

c = create_nested_dict()
like image 143
Noufal Ibrahim Avatar answered May 18 '26 18:05

Noufal Ibrahim


Since you have control over your objects placed inside the nested dict, just define addition and subtraction to them in a way that when added to an object, it simply returns the other object (effectvely behaving as a numerical 0 when added to numbers):

class NestedDict(dict):
    def __getitem__(self, key):
        if key in self: return self.get(key)
        return self.setdefault(key, NestedDict())
    def __add__(self, other):
        return other
    def __sub__(self, other):
        return other

And voilá:

>>> n = NestedDict()
>>> n["a"]["b"] += 1
>>> n["a"]["b"]
1
like image 29
jsbueno Avatar answered May 18 '26 19:05

jsbueno



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!