1

I have been trying to implement autovivification for python dictionary. I have referred the following links as well which has helped me to achieve what I wanted, but partially.

What is the best way to implement nested dictionaries?

How to implement autovivification for nested dictionary ONLY when assigning values?

This is the example I have been trying for my purpose

class MyDict(dict):

    def __setitem__(self, keys, value):
       if not isinstance(keys, tuple):
           return dict.__setitem__(self, keys, value)

       for key in keys[:-1]:
           self = self.setdefault(key, {})
       dict.__setitem__(self, keys[-1], value)

This is working for normal cases such as

my_dict = MyDict()
my_dict['a','b','c']=10

which results in : {'a': {'b': {'c': 10}}}

But how do i implement this which is very much possible with collections.defaultdict

my_dict['a']['b']['c'].append(10)

I don't want to implement defaultdict because of it's non-human-readable output and moreover it is not working with pickle.

Any suggestion would be appreciated.

Thank you

Pro
  • 305
  • 3
  • 13
  • Subclass `defaultdict` to customize its `__repr__` and allow it to be pickled? (Seems to work fine with pickle to me, though.) – Ry- Sep 15 '19 at 14:27
  • Thanks for the quick response. One more reason I want to avoid defaultdict is , initialization gets uglier when the dictionary is deeply nested. – Pro Sep 15 '19 at 14:35
  • Although I tried this way as well `tree = lambda: defaultdict(tree)`, but I failed to handle this case in a recursive way - `defaultdict(lambda : defaultdict(lambda : defaultdict(list)))` – Pro Sep 15 '19 at 14:39
  • `tree = lambda: defaultdict(tree)` didn’t work? – Ry- Sep 15 '19 at 14:48
  • Hi, Actually it is working for dictionary of dictionaries but I am not able to come up with a code for *dict-of-dict-of-list* as i mentioned in my previous comment. – Pro Sep 15 '19 at 14:51
  • If the structure is fixed, you can come up with a function that creates `defaultdict(lambda: defaultdict(lambda: defaultdict(list)))` from `(3, list)`. If it isn’t, you can subclass `defaultdict` to add `append` and whatever else is necessary to act like a list, but that’s kind of messy and I’d make a function that initializes `my_dict['a']['b']['c'] = []` instead. – Ry- Sep 15 '19 at 14:56
  • Hmm. How would you know that `my_dict['a']['b']` should be a `dict` but `my_dict['a']['b']['c'] should be a `list`? – petre Sep 15 '19 at 15:01
  • Here is my solution at this link: https://stackoverflow.com/a/70319015/11397243 – snoopyjc Dec 12 '21 at 06:21

0 Answers0