Могут быть способы сделать это только с использованием строковой обработки, но я бы проанализировал их и напечатал их в формате newick рекурсивно. Несколько минимальная реализация:
import re
class Tree(object):
def __init__(self, label):
self.label = label
self.children = []
@staticmethod
def _tokenize(string):
return list(reversed(re.findall(r'\(|\)|[^ \n\t()]+', string)))
@classmethod
def from_string(cls, string):
tokens = cls._tokenize(string)
return cls._tree(tokens)
@classmethod
def _tree(cls, tokens):
t = tokens.pop()
if t == '(':
tree = cls(tokens.pop())
for subtree in cls._trees(tokens):
tree.children.append(subtree)
return tree
else:
return cls(t)
@classmethod
def _trees(cls, tokens):
while True:
if not tokens:
raise StopIteration
if tokens[-1] == ')':
tokens.pop()
raise StopIteration
yield cls._tree(tokens)
def to_newick(self):
if self.children and len(self.children) == 1:
return ','.join(child.to_newick() for child in self.children)
elif self.chilren:
return '(' + ','.join(child.to_newick() for child in self.children) + ')'
else:
return self.label
Обратите внимание, что, конечно, теряется информация в процессе преобразования, так как только терминальные узлы сохраняются. Использование:
>>> s = """(ROOT (..."""
>>> Tree.from_string(s).to_newick()
...
Большое вам спасибо =) –
я скопировал его почти дословно из моей [файл различных функций NLP] (https://github.com/L3viathan/toolib/blob/master/nlp.py) (может быть полезно, если вы работаете с деревьями синтаксического анализа), просто нужно добавить 'to_newick'. – L3viathan
Извините, но я вас не понял! Я скопировал ваш код, но он не работает :( –