Допустим, у меня есть список Python 3.6, который выглядит следующим образом:
l1 = [
[a,b,c],
[b,c],
[c],
[d, e],
[e]
...
]
Мне нужно преобразовать его в древовидную структуру, используя anytree , чтобы он выглядел таккак это:
>>> print(RenderTree(l1))
l1
|__ a
| |__b
| |__c
|___d
|__e
Считайте, что объекты a
, b
, c
, d
, e
являются строкой, если это помогает каким-либо образом.В настоящее время я прочитал много документации для anytree и некоторое время искал в StackOverflow, но не смог найти ничего, что помогло бы мне решить эту проблему.Каким самым питоническим способом я могу решить эту проблему?
Редактировать: Чтобы добавить пояснение, исходный список l1
должен представлять дерево, где первый элемент в l1
является родительским узлом, икаждый узел внутри него является дочерним узлом.Каждый дочерний узел может быть дочерним узлом перед ним и т. Д.
Редактировать Редактировать: Итак, вот как выглядит (гипотетически) исходный список:
l1 = [
['a', 'b', 'c'],
['b', 'c'],
['c'],
['d', 'e'],
['e']
]
Здесьпервый элемент каждого подсписка всегда будет родительским для этой ветви.Соединение каждой из этих веток привело бы к получению нужного мне формата, но я изо всех сил пытался выразить это словами (сейчас 2 часа ночи).Вот некоторые из моих попыток:
Для преобразования списка в узлы:
from anytree import Node
l = []
for x in l1:
a = Node(x[0])
for i in x[1:]:
Node(i, parent = a)
l.append(a)
Однако это возвращает дерево / список так:
>>> l
[Node('/a'), Node('/b'), Node('/c'), Node('/d'), Node('/e')]
>>> print(RenderTree(l[0]))
Node('/a')
├── Node('/a/b')
└── Node('/a/c')
>>> print(RenderTree(l[1]))
Node('/b')
└── Node('/b/c')
>>> print(RenderTree(l[2]))
Node('/c')
>>> print(RenderTree(l[3]))
Node('/d')
└── Node('/d/e')
>>> print(RenderTree(l[4]))
Node('/e')
Для фильтрацииВ этом случае я попытался сделать следующее:
def tuple_replace(tup, pos, val):
return tup[:pos] + (val,) + tup[pos+1:]
>>> l2=[]
>>> for pos, x in enumerate(l):
for pos_2, i in enumerate(x.children):
for j in l[pos+1:]:
if j.name == i.name:
x.children = tuple_replace(x.children, pos_2, i)
break
l2.append(x)
>>> for x in l2:
print(RenderTree(x))
Node('/a')
├── Node('/a/b')
└── Node('/a/c')
Node('/a')
├── Node('/a/b')
└── Node('/a/c')
Node('/b')
└── Node('/b/c')
Node('/d')
└── Node('/d/e')
Это шаг, на котором я сейчас нахожусь
Редактировать Редактировать редактировать:
Итак, путь дереваПредставлено, что у меня есть функция, которая возвращает список вроде l1
, и имеет следующую логику:
Каждый элемент в списке состоит из 2 частей.Родитель и дети.Родитель является первым элементом в списке, а все остальное - это его дети, или это дети детей и так далее.Таким образом, такие элементы, как: [a, b, c]
и [d, e, f, g]
представляют все элементы в ветви, а не только непосредственные родители, которые продолжают падать.Вот где остальные элементы вступают в игру.Следующий элемент обычно содержит первый дочерний элемент родителя: [b, c]
и [e, f]
и [g]
.Но теперь элемент [d, e, f, g]
отличается от [a, b, c]
, потому что внутри него есть две разные ветви, а не одна.Таким образом, дерево, такое как это:
l1
|
|_a
| |__b
| |__c
|
|_d
|__e
| |__f
|__g
Будет описываться как:
Редактировать: исправлено дерево ввода, потому что f
не имеет отдельной ветви
l1=[
[a,b,c],
[b, c],
[c],
[d,e,f,g],
[e,f]
[f]
[g]
]