# [Tutor] creating a nested dictionary

Ricardo Aráoz ricaraoz at gmail.com
Fri Jan 25 14:26:04 CET 2008

```Kent Johnson wrote:
> Remco Gerlich wrote:
>> I can't think of a really good generalization, one that will work for
>> all depths. That's the sort of thing you use Lisp, combinators and lots
>> of coffee for. Perhaps later today.
>
> Some nice solutions here:
>
> Kent

These solutions sometimes may have unexpected behavior.

class recursivedefaultdict(object):
def __init__(self):
self.__dd = defaultdict(recursivedefaultdict)
def __getattr__(self,attr):
return self.__dd.__getattribute__(attr)
def __getitem__(self,*args):
return self.__dd.__getitem__(*args)
def __setitem__(self,*args):
return self.__dd.__setitem__(*args)

d = recursivedefaultdict()
d['pepe']['jose']['juan'] = 25
d['pepe']['jose'] = 25
d['pepe']['martin'] = 33
[i for i in d['pepe']]

And it went into an infinite loop.

class recursivedefaultdict(defaultdict):
def __init__(self):
self.default_factory = type(self)
d = recursivedefaultdict()
d['pepe']['jose']['juan'] = 25
d['pepe']['jose'] = 25
d['pepe']['martin'] = 33
d
it prints : defaultdict(<class '__main__.hash'>, {'pepe':
defaultdict(<class '__main__.hash'>, {'jose': defaultdict(<class
'__main__.hash'>, {'juan': 25}), 'pedro': 25, 'martin': 33})})

[i for i in d['pepe']]
it prints : ['jose', 'pedro', 'martin']
expected  : [defaultdict(<class '__main__.hash'>, {'jose':
defaultdict(<class '__main__.hash'>, {'juan': 25}), 'pedro': 25,
'martin': 33})]

[i for i in d]
it prints : ['pepe']
expected  : [defaultdict(<class '__main__.hash'>, {'pepe':
defaultdict(<class '__main__.hash'>, {'jose': defaultdict(<class
'__main__.hash'>, {'juan': 25})})})]

Anyway it otherwise seems to behave properly :
a = d['pepe']
a
it prints : defaultdict(<class '__main__.hash'>, {'jose':
defaultdict(<class '__main__.hash'>, {'juan': 25}), 'pedro': 25,
'martin': 33})

as would be expected.

And class hash behaves like this last one.
class hash(defaultdict):
def __init__(self):
defaultdict.__init__(self, hash)

```