0

次のコードを使用して、Python でツリー オブジェクトを作成しました。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re,sys,codecs

neg_markers_en=[u'not',u"napt",u'no',u'nobody',u'none',u'never']

class Node:
    def __init__(self,name=None,parent=None,sentence_number=0):
        self.name=name
        self.next=list()
        self.parent=parent
        self.depth=0
        self.n_of_neg=0
        self.subordinate=None
        self.foo=None

def print_node(self):
    print self.name,'contains',[(x.name,x.depth,x.foo) for x in self.next]
    for x in self.next:
        x.print_node()

def get_negation(self):


    for x in self.next:
        if x.n_of_neg!=0:
            print unicode(x.depth)+u' |||',
            try:
                x.look_for_parent_vp()
            except: print 'not in a VP',
            try:
                x.look_for_parent_sent()
            except: print '***'
        x.get_negation()


def look_for_parent_vp(self):

    if self.parent.name=='VP':
        self.parent.print_nont()
    else:
        self.parent.look_for_parent_vp()

def look_for_parent_sent(self):

    if self.parent.name=='S' or self.parent.name=='SBAR':
        #This is to send out to a text file, along with what it covers
        print '||| '+ self.parent.name,
        try:
            self.parent.check_subordinate()
            self.parent.print_nont()
            print '\n'
        except:
            print u'no sub |||',
            self.parent.print_nont()
            print '\n'
    elif self.parent=='None': print 'root |||'
    else:
        self.parent.look_for_parent_sent()


def print_nont(self):

    for x in self.next:
        if x.next==[]:
            print unicode(x.name),
        else: x.print_nont()


def mark_subordinate(self):

    for x in self.next:
        if x.name=='SBAR':
            x.subordinate='sub'
        else: x.subordinate='main'
        x.mark_subordinate()

def check_subordinate(self):

    if self.subordinate=='sub':
        print u'sub |||',
    else:
        self.parent.check_subordinate()


def create_tree(tree):

    #replace "n't" with 'napt' so to avoid errors in splitting
    tree=tree.replace("n't",'napt')
    lista=filter(lambda x: x!=' ',re.findall(r"\w+|\W",tree))

    start_node=Node(name='*NULL*')
    current_node=start_node

    for i in range(len(lista)-1):
        if lista[i]=='(':
            next_node=Node()
            next_node.parent=current_node
            next_node.depth=current_node.depth+1
            current_node.next.append(next_node)
            current_node=next_node
        elif lista[i]==')':
            current_node=current_node.parent
        else:
            if lista[i-1]=='(' or lista[i-1]==')':
                current_node.name=lista[i]
            else:
                next_node=Node()
                next_node.name=lista[i]
                next_node.parent=current_node
                #marks the depth of the node
                next_node.depth=current_node.depth+1
                if lista[i] in neg_markers_en:
                    current_node.n_of_neg+=1
                current_node.next.append(next_node)


return start_node

これで、すべてのノードがリンクされ、親ノードの子ノードがリストに追加され、これらの子ノードのそれぞれがインスタンスの親を介して親に参照されます。次の問題があります。名前が 'S' または 'SBAR' である各ノード ( と呼びましょうnode_to_check) について、その子ノードの名前が 'S' または 'SBAR' であるかどうかを確認する必要があります。そうでない.foo場合は、の属性をnode_to_check「atom」に変換します。

私は次のようなことを考えていました:

def find_node_to_check(self):
    for next in self.next:
        if next.name == 'S' or next.name == 'SBAR':
        is_present = check_children(next)
        if is_present == 'no':
            find_node_to_check(next)
        else:
            self.foo = 'atom'

def check_children(self):
    for next in self.next:
        # is this way of returning correct?
        if next.name == 'S' or next.name == 'SBAR':
            return 'no'
        else:
            check_sents(next)
            return 'yes'

これまでに書いたコードも質問に含めました。ツリー構造は関数 create_tree(tree); で作成されます。入力ツリーは、スタンフォード パーサーのブラケット表記です。

4

1 に答える 1

0

新しいクラスを設計しようとするとき、何をする必要があるかを知ることは、それをどのように構築するかを教えてくれます。ここではスタブ化がうまく機能します。たとえば、次のようになります。

class Node:
   """A vertex of an n-adic tree"""

   def __init__(self, name):
       """since you used sentence, I assumed n-adic
          but that may be wrong and then you might want
          left and right children instead of a list or dictionary
          of children"""
       pass

   def append_children(self, children):
       """adds a sequence of child Nodes to self"""
       pass

   def create_child(self, name):
       """creates a new Named node and adds it as a child"""
       pass

   def delete_child(self, name):
       """deletes a named child from self or throws exception"""
       pass

等々。子供は注文する必要がありますか?ノード (および子孫) を削除する必要はありますか? 子供のリストを事前に作成できますか、それとも一度に 1 つずつ作成する必要がありますか。Node が端末であるという事実を本当に保存したいですか (それは冗長です)、それともis_terminal()を返したいchildren is Noneですか?

于 2013-06-24T15:19:13.443 に答える