2016-09-25 4 views

ответ

0

Могут быть способы сделать это только с использованием строковой обработки, но я бы проанализировал их и напечатал их в формате 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() 
... 
+0

Большое вам спасибо =) –

+0

я скопировал его почти дословно из моей [файл различных функций NLP] (https://github.com/L3viathan/toolib/blob/master/nlp.py) (может быть полезно, если вы работаете с деревьями синтаксического анализа), просто нужно добавить 'to_newick'. – L3viathan

+0

Извините, но я вас не понял! Я скопировал ваш код, но он не работает :( –

Смежные вопросы