Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pythonic way to create 3d dict

Tags:

python

I want to create a dict which can be accessed as:

d[id_1][id_2][id_3] = amount

As of now I have a huge ugly function:

 def parse_dict(id1,id2,id3,principal, data_dict):
        if data_dict.has_key(id1):
           values = data_dict[id1]
           if values.has_key[id2]
              ..
        else:
            inner_inner_dict = {}
             # and so on

What is the pythonic way to do this?

note, that i input the principal.. but what i want is the amount.. So if all the three keys are there.. add principal to the previous amount!

Thanks

like image 463
frazman Avatar asked Aug 28 '12 20:08

frazman


4 Answers

You may want to consider using defaultdict:

For example:

json_dict = defaultdict(lambda: defaultdict(dict))

will create a defaultdict of defaultdicts of dicts (I know..but it is right), to access it, you can simply do:

json_dict['context']['name']['id'] = '42'

without having to resort to using if...else to initialize.

like image 87
K Z Avatar answered Nov 07 '22 23:11

K Z


from collections import defaultdict

d = defaultdict(lambda : defaultdict(dict))

d[id_1][id_2][id_3] = amount
like image 41
Hayk Martiros Avatar answered Nov 07 '22 23:11

Hayk Martiros


You can make a simple dictionary that creates new ones (using Autovivification):

>>> class AutoDict(dict):
    def __missing__(self, key):
        x = AutoDict()
        self[key] = x
        return x

>>> d = AutoDict()
>>> d[1][2][3] = 4
>>> d
{1: {2: {3: 4}}}

This will have no limit of dimensions as the defaultdict with dict has.

Or a simpler version using defaultdict (from the above wiki link):

def auto_dict():
    return defaultdict(auto_dict)
like image 5
JBernardo Avatar answered Nov 08 '22 00:11

JBernardo


>>> from collections import defaultdict
>>> import json

>>> def tree(): return defaultdict(tree)

>>> t = tree()
>>> t['a']['b']['c'] = 'foo'
>>> t['a']['b']['d'] = 'bar'
>>> json.dumps(t)
'{"a": {"b": {"c": "foo", "d": "bar"}}}'
like image 5
applicative_functor Avatar answered Nov 07 '22 23:11

applicative_functor