2013-05-14 1 views
4

Я пытаюсь преобразовать список разделенных точками строк, например.преобразовать список строк с разделителями в дерево/вложенный dict, используя python

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

в дерево (вложенные списки или дикты - все, что легко пройти). Реальные данные имеют от 1 до 4 разделенных точками частей разной длины и всего 2200 записей. Моя фактическая цель состоит в том, чтобы заполнить набор из 4 QComboBox'ов этими данными таким образом, чтобы 1-й QComboBox был заполнен первым набором элементов ['one', 'five', '12'] (без дубликатов). Затем, в зависимости от выбранного элемента, второй QComboBox заполняется связанными с ним элементами: для «одного» это будет: ['two', 'six'] и т. Д., Если есть другой вложенный уровень.

До сих пор у меня есть рабочий список -> вложенное решение dicts, но это ужасно медленно, так как я использую регулярный dict(). И у меня, похоже, есть проблема с переделкой его на defaultdict, чтобы легко справиться с заполнением ComboBoxes должным образом.

Мой текущий код:

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

Yay, это великолепно! Спасибо за ваш быстрый ответ. Теперь я просто должен научить его разрезать диктофон. –

+0

Не могли бы вы рассказать код нарезки (получение набора ключей в зависимости от выбранной клавиши более высокого уровня) так же легко? Кажется, я, как правило, ставил рекурсию в странные места, в то время как ваш код просто шокировал меня своей простотой. –

+0

@python_head: Я не совсем уверен, что вы имеете в виду ... Учитывая вышеприведенную структуру и ключ «один» - что должен вернуть код нарезки? – georg

Смежные вопросы