Я не могу разобрать желаемый результат - кажется, что в нем больше открытых скобок, чем в соответствующих закрытых, и я не понимаю логику, стоящую за ним.
Чтобы сделать древовидную структуру явной, как насчетНапример:
data = '''* list item 1
* list item 2
** list item 3
** list item 4
*** list item 5
* list item 6'''.splitlines()
class Node(object):
def __init__(self, payload):
self.payload = payload
self.children = []
def show(self, indent):
print ' '*indent, self.payload
for c in self.children:
c.show(indent+2)
def makenest(linelist):
rootnode = Node(None)
stack = [(rootnode, 0)]
for line in linelist:
for i, c in enumerate(line):
if c != '*': break
stars, payload = line[:i], line[i:].strip()
curlev = len(stars)
curnod = Node(payload)
while True:
parent, level = stack[-1]
if curlev > level: break
del stack[-1]
# a child node of the current top-of-stack
parent.children.append(curnod)
stack.append((curnod, curlev))
rootnode.show(0)
makenest(data)
Метод show
, конечно, существует только для проверки правильности работы части о разборе строк и создании дерева.Если вы можете более точно указать, как именно вы хотите преобразовать свое дерево во вложенные кортежи и списки, я уверен, что будет легко добавить в класс Node
соответствующий (и, вероятно, рекурсивный) метод - так,не могли бы вы дать эту недостающую спецификацию ...?
Редактировать : поскольку ОП уточнил, что, как и предсказывалось, стало легко удовлетворить спецификацию.Просто добавьте к class Node
следующий метод:
def emit(self):
if self.children:
return (self.payload,
[c.emit() for c in self.children])
else:
return (self.payload,)
и измените последние три строки кода (последнюю из makenest
, пустую и вызов уровня модуля на makenest
) to:
return [c.emit() for c in rootnode.children]
print(makenest(data))
(круглые скобки после print
избыточны, но безвредны в Python 2, обязательны для Python 3, поэтому я поставил их там на всякий случай; -).
С этими крошечными изменениями мой код запускается в соответствии с запросом и теперь выдает
[('list item 1',), ('list item 2', [('list item 3',), ('list item 4', [('list item 5',)])]), ('list item 6',)]