Вложенный список в строку - PullRequest
0 голосов
/ 03 июля 2011

У меня есть список экземпляров класса Test.Этот класс имеет метод, подобный name и parent

[Test('a', ''), Test('b', ''), Test('c', 'a'), Test('d', 'a'), Test('e', 'c')]

Первый аргумент - имя, второй родитель.Родительский аргумент - это просто аргумент name родительского класса.Я хочу преобразовать этот список в строку типа:

Test('a', '')
  |-- Test('c', 'a')
        |-- Test('e', 'c')
  |-- Test('d', 'a')
Test('b', '')

Я ищу наиболее эффективный для процессора способ преобразования этого списка в строку.Элементы в списке могут быть вложены в несколько уровней (10 100, 1000, ..), и мне наплевать на используемую память.

Ответы [ 3 ]

2 голосов
/ 03 июля 2011

Вот код, который работает как есть.По сути, преобразуйте массив в дерево, а затем используйте рекурсивную DFS, чтобы распечатать его (вы можете использовать итеративную DFS, если хотите):

class Test:
    def __init__(self, name, parent):
        self.name = name
        self.parent = parent
    def __repr__(self):
        return "Test('"+self.name+"', '"+self.parent+"')"



li = [Test('a', ''), Test('b', ''), Test('c', 'a'), Test('d', 'a'), Test('e', 'c')]

dict = {"":(None,[])} #name to (node,children)
#add nodes
for item in li:
    dict[item.name] = (item, [])
#add children
for item in li:
    dict[item.parent][1].append(dict[item.name])

def printTree(dict, name, indent):
    newIndent=indent
    if name!="":
        print(indent + str(dict[name][0]))
        if indent == "": newIndent="  |-- "
        else: newIndent = "      "+indent
    for child in dict[name][1]:
        printTree(dict, child[0].name, newIndent) 


printTree(dict, "", "")
0 голосов
/ 03 июля 2011

Если вы в конечном итоге используете DFS в качестве пятерки, вы можете использовать networkx

import networkx as nx
stuff=[('a', ''), ('b', ''), ('c', 'a'), ('d', 'a'), ('e', 'c')]
G=nx.DiGraph()
for i in stuff:
    G.add_edge(i[1],i[0])
print G.adj

Тогда итерация этого с DFS

0 голосов
/ 03 июля 2011

Вы должны использовать другой контейнер, например:

class Test:
    def __init__(self, name, sub=None):
        self.name = name
        self.sub = sub if sub is not None else []

elements = [Test('a', [Test('c', [Test('e')]), Test('d')]), Test('b')]

, затем просто итерируйте elements, чтобы напечатать:

def show(x, indent=0):
    for i in x:
        print('\t'*indent + 'Test(%r)' % i.name)
        show(i.sub, indent+1)

show(elements)

следует напечатать:

Test('a')
    Test('c')
        Test('e')
    Test('d')
Test('b')

Вы можете изменить отступ на любой, какой пожелаете (я использую вкладки).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...