2010-04-29 5 views
0

나는이의 모습과 유사한 튜플파이썬 : 경로 목록에서 중첩 된 사전을 만든이

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

(Obj.part보다 더 복잡한 경로 이러한 튜플 14,000 이상이있다, 여기 간체)의 목록을 가지고

여기서 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} } 
     } 

모양을 중첩 된 사전을 만들 현재 두 가지 일을하고 있습니다. 1. 사전 get/set에 도트 표기법을 사용할 수 있도록 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을 가리킨다.

더 좋은 방법이 있나요?

답변

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 사용 – Rescommunes

관련 문제