Конвертировать список разделенных строк в дерево/вложенный dict, используя python
Я пытаюсь преобразовать список разделенных точками строк, например.
['one.two.three.four', 'one.six.seven.eight', 'five.nine.ten', 'twelve.zero']
в дерево (вложенные списки или dicts - все, что легко пройти).
Реальные данные имеют от 1 до 4 разделенных точками частей разной длины и всего 2200 записей.
Моя фактическая цель состоит в том, чтобы заполнить набор из 4 QComboBox'ов этими данными таким образом, чтобы 1-й QComboBox был заполнен первыми наборами элементов ['one', 'five', '12'] (без дубликатов). Затем, в зависимости от выбранного элемента, второй QComboBox заполняется связанными с ним элементами: для 'one' это будет: ['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)
Ответы
Ответ 1
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": {}
}
}
}
}