首页 > 解决方案 > 如何将 listiterator 对象转换为树对象?

问题描述

我想通过运行 find_pattern.py 来提取解析树,它们与以下模式匹配:

SIMPLE_PREDICATE = (ROOT, ((SENTENCE, (NP, VP, PERIOD)),))          
APPOSITION = (SENTENCE, ((NP, (NP, COMMA, NP, COMMA)), VP, PERIOD)) 

但以下输出显示:

Traceback (most recent call last):
 File "C:\Users\Anon\Desktop\ZAHID\Working Model 1\zahid\Practice\New folder\find_pattern.py", line 40, in <module>
appos = sent_extract.find_appositions(parse_trees)
 File "C:\Users\Anon\Desktop\ZAHID\Working Model 1\zahid\Practice\New folder\sent_extract.py", line 30, in find_appositions
s in search_for_matches(parse_tree, APPOSITION)]
 File "C:\Users\Anon\Desktop\ZAHID\Working Model 1\zahid\Practice\New folder\sent_extract.py", line 58, in search_for_matches
if is_match(parse_tree, pattern):
 File "C:\Users\Anon\Desktop\ZAHID\Working Model 1\zahid\Practice\New folder\sent_extract.py", line 45, in is_match
if tree.label() == parent and len(tree) == len(children): 
AttributeError: 'listiterator' object has no attribute 'label'

find_pattern.py

import os
import parse_article
import stanford_parser
import sent_extract

article_filename = 'C:\Users\Anon\Desktop\ZAHID\Working Model 1\zahid\Practice\New folder\____.html'

sentences = parse_article.parse_html(article_filename)

user='' 
parser = stanford_parser.create_parser(user)
parse_trees = parser.raw_parse_sents(sentences)

appos = sent_extract.find_appositions(parse_trees)
print(appos)

sent_extract.py

from nltk.tree import Tree
from tags import *

SIMPLE_PREDICATE = (ROOT, ((SENTENCE, (NP, VP, PERIOD)),))          
APPOSITION = (SENTENCE, ((NP, (NP, COMMA, NP, COMMA)), VP, PERIOD)) 

def find_predicates(parse_trees):
  preds = []
  for parse_tree in parse_trees:
    if is_match(parse_tree, SIMPLE_PREDICATE):         
      preds.append(parse_tree[0])
  return preds

def find_appositions(parse_trees):
  appos = []
  for parse_tree in parse_trees:
    appos += [(s[0,0], s[0,2]) for
        s in search_for_matches(parse_tree, APPOSITION)]
  return appos


def is_match(tree, pattern):
  if not isinstance(pattern, tuple):
    return tree.label() == pattern

  else:
    parent = pattern[0]
    children = pattern[1]
    if tree.label() == parent and len(tree) == len(children): 
      for i in xrange(len(tree)):
        ith_child = tree[i]
        if not is_match(ith_child, children[i]):
          return False
      return True

def search_for_matches(parse_tree, pattern):
  matches = []
  if is_match(parse_tree, pattern):
    matches.append(parse_tree)
  for child in parse_tree:
    if isinstance(child, Tree):
      matches += search_for_matches(child, pattern)
  return matches

标签.py

ADJP = 'ADJP'
ADVP = 'ADVP'
NUMBER = 'CD'
DET = 'DT'
PREP = 'IN'
ADJ = 'JJ'
ADJ_COMP = 'JJR'
ADJ_SUP = 'JJS'
MODAL = 'MD'
NOUN = 'NN'
NOUN_PROPER = 'NNP'
NOUN_PL = 'NNS'
NP = 'NP'
POSS = 'POS'
PP = 'PP'
PRONOUN = 'PRP'
PRONOUN_POSS = 'PRP$'
ADVERB = 'RB'
ROOT = 'ROOT'
SENTENCE = 'S'
SBAR = 'SBAR'
WH_QUESTION = 'SBARQ'
BIN_QUESTION = 'SQ'
TO = 'TO'
VERB_INF = 'VB'
VERB_PAST = 'VBD'
VERB_PLURAL = 'VBP'
VERB_3SG = 'VBZ'
VP = 'VP'
WHNP = 'WHNP'
WHADJP = 'WHADJP'
WHADVP = 'WHADVP'
WDT = 'WDT'
WP_POSS = 'WP$'
COMMA = ','
PERIOD = '.'

标签: python

解决方案


raw_parse_sents()方法旨在处理多个句子。每个句子都被解析为一系列树,但您的代码假设每个句子都有一个树。从文档中:

返回类型: iter(iter(Tree))

所以你得到了一个可迭代的树。

所以而不是使用

for parse_tree in parse_trees:
    if is_match(parse_tree, SIMPLE_PREDICATE):         
        preds.append(parse_tree[0])

你必须使用

for sentence in parse_trees:
    for parse_tree in sentence:
        if is_match(parse_tree, SIMPLE_PREDICATE):         
            preds.append(parse_tree[0])

现在您正在传递实际Tree()实例,它们是可以被索引并具有长度的类似列表的对象。

这同样适用于find_appositions()

def find_appositions(parse_trees):
    appos = []
    for sentence in parse_trees:
        for parse_tree in sentence:
            appos += [(s[0,0], s[0,2]) for
                      s in search_for_matches(parse_tree, APPOSITION)]
    return appos

推荐阅读