Python: Created nested dictionary from list of paths

Posted by sberry2A on Stack Overflow See other posts from Stack Overflow or by sberry2A
Published on 2010-04-29T14:32:40Z Indexed on 2010/04/29 18:57 UTC
Read the original article Hit count: 264

Filed under:
|

I have a list of tuples the looks similar to this (simplified here, there are over 14,000 of these tuples with more complicated paths than Obj.part)

[ (Obj1.part1, {<SPEC>}), (Obj1.partN, {<SPEC>}), (ObjK.partN, {<SPEC>}) ]

Where Obj goes from 1 - 1000, part from 0 - 2000. These "keys" all have a dictionary of specs associated with them which act as a lookup reference for inspecting another binary file. The specs dict contains information such as the bit offset, bit size, and C type of the data pointed to by the path ObjK.partN.

For example: Obj4.part500 might have this spec, {'size':32, 'offset':128, 'type':'int'} which would let me know that to access Obj4.part500 in the binary file I must unpack 32 bits from offset 128.

So, now I want to take my list of strings and create a nested dictionary which in the simplified case will look like this

data = { 'Obj1' : {'part1':{spec}, 'partN':{spec} }, 
         'ObjK' : {'part1':{spec}, 'partN':{spec} }
       }

To do this I am currently doing two things, 1. I am using a dotdict class to be able to use dot notation for dictionary get / set. That class looks like this:

class dotdict(dict):
    def __getattr__(self, attr):
        return self.get(attr, None)
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__

The method for creating the nested "dotdict"s looks like this:

def addPath(self, spec, parts, base):
    if len(parts) > 1:
        item = base.setdefault(parts[0], dotdict())
        self.addPath(spec, parts[1:], item)
    else:
        item = base.setdefault(parts[0], spec)
    return base

Then I just do something like:

for path, spec in paths:
    self.lookup = dotdict()
    self.addPath(spec, path.split("."), self.lookup)

So, in the end
self.lookup.Obj4.part500 points to the spec.

Is there a better (more pythonic) way to do this?

© Stack Overflow or respective owner

Related posts about python

Related posts about beginner