Придание иерархии списку заголовков

У меня есть этот список в 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, но не получил желаемого результата. Я хочу придать структуру списку. Как дерево или что-то подобное.

какова логика вашей иерархии? цифры? а если никого нет?

Bending Rodriguez 16.04.2024 13:56

Структурированное представление желаемого результата: |_'13.3. Риск' |____' 13.3.1. Стратегия' | |____'Субстратегия' |____'13.3.2. Токен' |____'Материал' |____'Воздействие' |____'Алинг'

Sebas Fernández 16.04.2024 13:56

добавьте это к вопросу, он не очень хорошо отформатирован в комментариях;)

Bending Rodriguez 16.04.2024 13:57

логика была бы в этом случае цифры да. Если номера нет, этот заголовок будет зависеть от предыдущего, как показано. |_'13.3. Риск' |____' 13.3.1. Стратегия' | |____'Субстратегия' |____'13.3.2. Токен' |____'Материал' |____'Воздействие' |____'Алинг'

Sebas Fernández 16.04.2024 13:58

Какой результат вы хотите? Эта визуализация?

JonSG 16.04.2024 15:27

Структура. Список/Дикт. Визуализация нужна только для того, чтобы увидеть результат :)

Sebas Fernández 17.04.2024 09:19
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
6
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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? и черные пробелы в заголовке?

Sebas Fernández 17.04.2024 10:48

Я добавил 2 вещи в ваше решение, и теперь оно работает! Я редактирую его, чтобы завершить :) Спасибо.

Sebas Fernández 17.04.2024 11:06

Я не могу проголосовать за вас, так как у меня нет репутации :(

Sebas Fernández 17.04.2024 11:13

Вы можете построить иерархию во вложенных словарях. Просматривая список заголовков, отслеживайте текущих родителей последней «ветви» дерева. Поднимитесь вверх по родительским уровням, если главы не являются подуровнями:

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': {}
          }
      }
 }

Я не могу проголосовать за вас, так как у меня нет репутации :(

Sebas Fernández 17.04.2024 11:14

@SebasFernández Вы должны выбрать ответ, который, по вашему мнению, лучше всего решит вашу проблему для вас и для любого пользователя в будущем, у которого возникнет аналогичный вопрос, и выбрать его как «принятый ответ».

JonSG 17.04.2024 17:49

Другие вопросы по теме