2010-04-29 109 views
0

我的元組類似於此(這裏簡化,有超過這些元組14000比Obj.part更復雜的路徑)的Python:創建嵌套的字典從路徑列表

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

列表

其中Obj從1到1000,部分從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} } 
     } 

要做到這一點,我我目前正在做兩件事情,1.我正在使用一個dotdict類,以便能夠使用點表示法來獲取/設置字典。這個類看起來是這樣的:

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

創建嵌套 「dotdict」 S的方法是這樣的:

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指向規範。

有沒有更好的(更pythonic)的方式來做到這一點?

回答

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 

如果每個路徑(ObjNpartN說),你可能只是這樣做只有兩個部件:

specs = {} 
for path, spec in paths: 
    [obj, part] = path.split('.') 
    specs.setdefault(obj, {})[part] = spec 
+0

+1 awsome使用setdefault – Rescommunes 2012-11-06 04:57:03