У меня есть список кортежей, который выглядит примерно так (здесь упрощенно, существует более 14 000 таких кортежей с более сложными путями, чем Obj.part)
[ (Obj1.part1, {<SPEC>}), (Obj1.partN, {<SPEC>}), (ObjK.partN, {<SPEC>}) ]
Где Obj идет от 1 до 1000, от 0 до 2000. Все эти «ключи» имеют словарь спецификаций, связанных с ними, которые служат справочной информацией для проверки другого двоичного файла. DECTS спецификация содержит информацию, такую как смещение бита, размер бита и тип C данных, на которые указывает путь ObjK.partN.
Например: Obj4.part500 может иметь эту спецификацию, {'size': 32, 'offset': 128, 'type': 'int'}, которая позволит мне узнать это для доступа к Obj4.part500 в двоичном файле Я должен распаковать 32 бита со смещения 128.
Итак, теперь я хочу взять мой список строк и создать вложенный словарь, который в упрощенном случае будет выглядеть так
data = { 'Obj1' : {'part1':{spec}, 'partN':{spec} },
'ObjK' : {'part1':{spec}, 'partN':{spec} }
}
Для этого я сейчас делаю две вещи: 1. Я использую класс dotdict, чтобы иметь возможность использовать точечную нотацию для словаря get / set. Этот класс выглядит так:
class dotdict(dict):
def __getattr__(self, attr):
return self.get(attr, None)
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
Метод создания вложенных «дотдиктов» выглядит следующим образом:
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
указывает на спецификацию.
Есть ли лучший (более питонический) способ сделать это?