Резюме:
Я пытаюсь создать рекурсивную функцию, которая берет данные из списка смежности и преобразует их в точечную запись.
Подробности:
У меня есть эти данные в виде списка кортежей (Python). Данные сортируются по id
, но это единственное ограничение. Нет ограничений, что родительские элементы должны быть перечислены перед дочерними: например, элемент № 3 может иметь родителя, являющегося элементом № 7. Также нет (запланированного) ограничения на количество поколений.
id name parent | data = [
1 A 0 | (1, 'A', 0),
2 B 1 | (2, 'B', 1),
3 C 1 | ...
4 D 2 |
5 E 2 |
6 F 3 |
7 G 2 |
8 H 6 | ...
9 I 4 | (9, 'I', 4)]
Я хочу вернуть список строк в точечной нотации родитель-потомок:
A
A.B
A.B.D
A.B.D.I
A.B.E
A.B.G
A.C
A.C.F
A.C.F.H
Обратите внимание, что отображается каждое имя — другие алгоритмы, которые я нашел, будут возвращать только элементы, у которых нет дочерних элементов.
Что я пробовал:
Код Python:
Вот что у меня есть на данный момент, основанное на визуализации структуры данных USF здесь а>.
if len(cat_list) == 0:
return
for item in cat_list:
parent_id = item[0]
name = item[1]
children = [_x for _x in cat_list if _x[2] == parent_id]
if len(children) == 0:
# then we're at the end
return name
else:
sub_problem = cat_list[1:]
sub_solution = create_categories(sub_problem)
solution = "{}.{}".format(name, sub_solution)
print(solution)
return solution
Но все, что это делает, это берет один элемент и строит его полностью:
D.E
C.D.E
B.C.D.E
A.B.C.D.E
SQL:
Если данные хранились в базе данных SQLite и могли попасть туда частично с помощью следующего SQL:
SELECT
t1.name AS level1,
t2.name as level2,
t3.name as level3,
t4.name as level4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.id
LEFT JOIN category AS t3 ON t3.parent = t2.id
LEFT JOIN category AS t4 ON t4.parent = t3.id
WHERE t1.name = 'A'
Но это имеет несколько проблем:
- не масштабируется до произвольной глубины
- не возвращает промежуточные глубины
Из-за этих ограничений я решил реализовать код на Python.
Исследовать
Я просмотрел кучу разных вопросов и веб-сайтов, но ни один из них не дал мне момент «Эврика», поэтому я спрашиваю здесь.
Этот вопрос очень похож, но находится в vb.net, о котором я ничего не знаю. Это также не информирует меня о том, как выполнить конкатенацию.
Этот вопрос тоже очень похож, но опять же я не знаю языка. Похоже, что функция Lookup
может быть очень похожа на python dict...