2013-05-14 3 views
4

도트로 구분 된 문자열 목록을 변환하려고합니다.파이썬을 사용하여 구분 된 문자열 목록을 트리/중첩 된 dict로 변환합니다.

['one.two.three.four', 'one.six.seven.eight', 'five.nine.ten', 'twelve.zero'] 

트리 (중첩 목록 또는 dicts - 걷기 쉬운 모든 것). 실제 데이터에는 길이가 다른 1 ~ 4 개의 도트로 구분 된 부분이 있으며 총 2200 개의 레코드가 있습니다. 내 실제 목표는 첫 번째 QComboBox가 첫 번째로 설정된 항목 [ 'one', 'five', 'twelve'] (중복 없음)으로 채워지는 방식으로 4 개의 QComboBox 집합을이 데이터로 채우는 것입니다. 그런 다음 선택한 항목에 따라 두 번째 QComboBox의 관련 항목이 채워집니다. '1'의 경우 다른 중첩 수준이 있으면 [ 'two', 'six'] 등이됩니다.

지금까지 작업 목록 - 중첩 된 dicts 솔루션이 있지만 일반 dict()를 사용하기 때문에 끔찍하게 느립니다. 그리고 나는 ComboBox를 적절히 작성하는 것을 쉽게하기 위해 defaultdict로 재 설계하는 데 어려움이있는 것 같다.

내 현재 코드 :

def list2tree(m): 
    tmp = {} 
    for i in range(len(m)): 
     if m.count('.') == 0: 
      return m 
     a = m.split('.', 1) 
     try: 
      tmp[a[0]].append(list2tree(a[1])) 
     except (KeyError, AttributeError): 
      tmp[a[0]] = list2tree(a[1]) 
    return tmp 

main_dict = {} 
i = 0 
for m in methods: 
    main_dict = list2tree(m) 
    i += 1 
    if (i % 100) == 0: print i, len(methods) 
print main_dict, i, len(methods) 

답변

16
ls = ['one.two.three.four', 'one.six.seven.eight', 'five.nine.ten', 'twelve.zero'] 
tree = {} 

for item in ls: 
    t = tree 
    for part in item.split('.'): 
     t = t.setdefault(part, {}) 

결과 :

{ 
"twelve": { 
    "zero": {} 
}, 
"five": { 
    "nine": { 
    "ten": {} 
    } 
}, 
"one": { 
    "six": { 
    "seven": { 
    "eight": {} 
    } 
    }, 
    "two": { 
    "three": { 
    "four": {} 
    } 
    } 
} 
} 
+0

야호, 즉 멋지다! 귀하의 빠른 응답을 주셔서 감사합니다. 지금은 그냥 dicts의 단서를 조각 가르쳐. –

+0

슬라이스 코드 (선택한 상위 키에 따라 키 세트 가져 오기)를 쉽게 할 수 있습니까? 이상한 곳에서 재귀를 만드는 경향이있는 반면 코드는 단순함으로 나를 놀라게했습니다. –

+0

@python_head : 나는 당신이 무엇을 의미하는지 완전히 확신하지 못합니다 ... 위의 구조체와 키 'one'을 감안할 때 슬라이스 코드가 무엇을 반환해야합니까? – georg