Python:从路径列表创建嵌套字典

sbe*_*rry 0 python nested path

我有一个类似于此的元组列表(这里简化了,这些元组中有超过14,000个,其路径比Obj.part更复杂)

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

Obj从1 - 1000开始,部分从0到2000.这些"键"都有一个与它们相关的规范字典,它们用作检查另一个二进制文件的查找参考.规范dict包含诸如位偏移,位大小和路径ObjK.partN指向的数据的C类型之类的信息.

例如:Obj4.part500可能有这个规范,{'size':32,'offset':128,'type':'int'}这会让我知道要访问二进制文件中的Obj4.part500我必须解包来自偏移128的32位.

所以,现在我想获取我的字符串列表并创建一个嵌套字典,在简化的情况下将看起来像这样

data = { 'Obj1' : {'part1':{spec}, 'partN':{spec} }, 
         'ObjK' : {'part1':{spec}, 'partN':{spec} }
       }
Run Code Online (Sandbox Code Playgroud)

要做到这一点,我目前正在做两件事,1.我使用dotdict类,能够使用点符号进行字典获取/设置.那个班看起来像这样:

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

创建嵌套"dotdict"的方法如下所示:

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
Run Code Online (Sandbox Code Playgroud)

然后我做了类似的事情:

for path, spec in paths:
    self.lookup = dotdict()
    self.addPath(spec, path.split("."), self.lookup)
Run Code Online (Sandbox Code Playgroud)

所以,最后
self.lookup.Obj4.part500指向规范.

有没有更好的(更pythonic)方式来做到这一点?

tca*_*uce 7

除非您更喜欢使用点表示法访问规范,否则请尝试将它们直接放入字典中.在下面的代码中,名称d跟踪路径上访问的最里面的字典:

specs = {}
for path, spec in paths:
    parts = path.split('.')
    d = specs
    for p in parts[:-1]:
        d = d.setdefault(p, {})
    d[parts[-1]] = spec
Run Code Online (Sandbox Code Playgroud)

如果每个通道只有两个部件(ObjNpartN说),你可能只是这样做:

specs = {}
for path, spec in paths:
    [obj, part] = path.split('.')
    specs.setdefault(obj, {})[part] = spec
Run Code Online (Sandbox Code Playgroud)