У меня есть этот список в Python
titles = [
'13.3. Risk',
'13.3.1. Strategy',
'SubStrategy',
'13.3.2. Token',
'Material',
'Impact',
'Aling'
]
И я хотел бы создать иерархию, в результате чего получится что-то вроде этого:
|_'13.3. Risk'
|____'13.3.1. Strategy'
| |____'SubStrategy'
|____'13.3.2. Token'
|____'Material'
|____'Impact'
|____'Aling'
Я пробовал регулярное выражение, а также библиотеку Anytree, но не получил желаемого результата. Я хочу придать структуру списку. Как дерево или что-то подобное.
Структурированное представление желаемого результата: |_'13.3. Риск' |____' 13.3.1. Стратегия' | |____'Субстратегия' |____'13.3.2. Токен' |____'Материал' |____'Воздействие' |____'Алинг'
добавьте это к вопросу, он не очень хорошо отформатирован в комментариях;)
логика была бы в этом случае цифры да. Если номера нет, этот заголовок будет зависеть от предыдущего, как показано. |_'13.3. Риск' |____' 13.3.1. Стратегия' | |____'Субстратегия' |____'13.3.2. Токен' |____'Материал' |____'Воздействие' |____'Алинг'
Какой результат вы хотите? Эта визуализация?
Структура. Список/Дикт. Визуализация нужна только для того, чтобы увидеть результат :)
Я бы сделал два прохода, чтобы преобразовать ваши данные в иерархию. Я думаю, что это самое простое, чему нужно следовать. На практике я, вероятно, сделал бы это за один проход, но для большей ясности давайте сделаем это за два.
Данный:
titles = [
"13.3. Risk",
"13.3.1. Strategy",
"SubStrategy",
"13.3.2. Token",
"Material",
"Impact",
"Aling"
]
Шаг 1. Создайте словарь пронумерованных элементов и их прямых дочерних элементов.
results = {}
for title in titles:
if title[0].isnumeric():
key, name = title.split(" ")
key = key.strip(".")
current = results.setdefault(key, {"name": title, "children": []})
continue
current["children"].append(title)
В результате словарь будет выглядеть так:
{
"13.3": {
"name": "13.3. Risk",
"children": []
},
"13.3.1": {
"name": "13.3.1. Strategy",
"children": [
"SubStrategy"
]
},
"13.3.2": {
"name": "13.3.2. Token",
"children": [
"Material",
"Impact",
"Aling"
]
}
}
Шаг 2: Теперь мы можем перебирать его и агрегировать корни дерева(ов), устанавливая элементы как дочерние элементы соответствующего родителя. Обратите внимание: мы будем предполагать, что корень(и) — это узлы, родители которых не могут быть найдены.
roots = []
for key, value in results.items():
parent_key = key.rsplit(".", 1)[0]
if parent_key not in results:
roots.append(value)
continue
results[parent_key]["children"].append(value)
Теперь мы можем использовать наши корни:
for root in roots:
print("----------------------")
print(json.dumps(root, indent=4))
print("----------------------")
Даём нам:
----------------------
{
"name": "13.3. Risk",
"children": [
{
"name": "13.3.1. Strategy",
"children": [
"SubStrategy"
]
},
{
"name": "13.3.2. Token",
"children": [
"Material",
"Impact",
"Aling"
]
}
]
}
----------------------
Мне нравится это решение. но как, если слов больше 1? и черные пробелы в заголовке?
Я добавил 2 вещи в ваше решение, и теперь оно работает! Я редактирую его, чтобы завершить :) Спасибо.
Я не могу проголосовать за вас, так как у меня нет репутации :(
Вы можете построить иерархию во вложенных словарях. Просматривая список заголовков, отслеживайте текущих родителей последней «ветви» дерева. Поднимитесь вверх по родительским уровням, если главы не являются подуровнями:
titles = [
'13.3. Risk',
'13.3.1. Strategy',
'SubStrategy',
'13.3.2. Token',
'Material',
'Impact',
'Aling'
]
tree = dict() # complete hierarchy
branch = [('',tree)] # last branch (chapter, sub-level)
for title in titles:
chapter = title.split()[0] * title[:1].isdigit()
while chapter and not chapter.startswith(branch[-1][0]): # find parent,
branch.pop(-1) # back up hierarchy
leaf = branch[-1][1][title] = {} # add leaf node
if chapter: # when title is a chapter ,
branch.append((chapter,leaf)) # extend last branch
выход:
print(tree)
{
'13.3. Risk':
{'13.3.1. Strategy':
{'SubStrategy': {}},
'13.3.2. Token':
{'Material': {},
'Impact': {},
'Aling': {}
}
}
}
Я не могу проголосовать за вас, так как у меня нет репутации :(
@SebasFernández Вы должны выбрать ответ, который, по вашему мнению, лучше всего решит вашу проблему для вас и для любого пользователя в будущем, у которого возникнет аналогичный вопрос, и выбрать его как «принятый ответ».
какова логика вашей иерархии? цифры? а если никого нет?