J'ai une liste de tuples les ressemble à ceci (simplifié ici, il y a plus de 14 000 de ces tuples avec des chemins plus complexes que Obj.part)Python: Créé le dictionnaire imbriqué de la liste des chemins
[ (Obj1.part1, {<SPEC>}), (Obj1.partN, {<SPEC>}), (ObjK.partN, {<SPEC>}) ]
Où Obj va de 1 à 1000, partie de 0 à 2000. Ces "clés" ont toutes un dictionnaire de spécifications qui leur est associé et qui servent de références de recherche pour inspecter un autre fichier binaire. La spécification dict contient des informations telles que le décalage de bit, la taille de bit et le type C des données pointées par le chemin ObjK.partN. Par exemple: Obj4.part500 peut avoir cette spécification, {'size': 32, 'offset': 128, 'type': 'int'} ce qui me permettrait de savoir que pour accéder à Obj4.part500 dans le binaire Je dois déposer déballer 32 bits de l'offset 128.
donc, maintenant je veux prendre ma liste de chaînes et de créer un dictionnaire imbriqué qui, dans le cas simplifié ressemblera à ceci
data = { 'Obj1' : {'part1':{spec}, 'partN':{spec} },
'ObjK' : {'part1':{spec}, 'partN':{spec} }
}
pour ce faire, je Je fais actuellement deux choses, 1. J'utilise une classe dotdict pour être capable d'utiliser la notation par points pour le dictionnaire get/set. Cette classe ressemble à ceci:
class dotdict(dict):
def __getattr__(self, attr):
return self.get(attr, None)
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
La méthode de création imbriquée "dotdict" s ressemble à ceci:
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
Je viens de faire quelque chose comme:
for path, spec in paths:
self.lookup = dotdict()
self.addPath(spec, path.split("."), self.lookup)
Ainsi, à la fin
self.lookup.Obj4.part500
points à la spécification.
Existe-t-il une meilleure façon (plus pythonique) de faire cela?
+1 très bonne utilisation de setdefault – Rescommunes