Python:从路径列表创建嵌套字典
我有一个元组的列表,长得像这样(这里简化了一下,实际上有超过14,000个这样的元组,路径比Obj.part复杂得多)
[ (Obj1.part1, {<SPEC>}), (Obj1.partN, {<SPEC>}), (ObjK.partN, {<SPEC>}) ]
其中Obj的范围是1到1000,part的范围是0到2000。这些“键”都有一个与之相关的规格字典,作为查找参考,用来检查另一个二进制文件。规格字典包含的信息有位偏移、位大小和路径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} }
}
为此,我目前在做两件事,第一,我使用一个dotdict类,这样我就可以用点符号来获取和设置字典的值。这个类长这样:
class dotdict(dict):
def __getattr__(self, attr):
return self.get(attr, None)
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
创建嵌套“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
然后我只需做类似这样的事情:
for path, spec in paths:
self.lookup = dotdict()
self.addPath(spec, path.split("."), self.lookup)
所以,最后
self.lookup.Obj4.part500
指向这个规格。
有没有更好(更符合Python风格)的方法来做到这一点?
1 个回答
8
如果你不想用点号来访问规格,可以直接把它们放进字典里。在下面的代码中,名字 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
如果每条路径只有两个部分(比如说 ObjN
和 partN
),你可以这样做:
specs = {}
for path, spec in paths:
[obj, part] = path.split('.')
specs.setdefault(obj, {})[part] = spec