【问题标题】:Extract parent and child node from python tree representation从 python 树表示中提取父节点和子节点
【发布时间】:2015-04-02 02:16:27
【问题描述】:
[Tree('ROOT', [Tree('S', [Tree('INTJ', [Tree('UH', ['Hello'])]), Tree(',', [',']), Tree('NP', [Tree('PRP$', ['My']), Tree('NN', ['name'])]), Tree('VP', [Tree('VBZ', ['is']), Tree('ADJP', [Tree('JJ', ['Melroy'])])]), Tree('.', ['.'])])]), Tree('ROOT', [Tree('SBARQ', [Tree('WHNP', [Tree('WP', ['What'])]), Tree('SQ', [Tree('VBZ', ['is']), Tree('NP', [Tree('PRP$', ['your']), Tree('NN', ['name'])])]), Tree('.', ['?'])])])]

我在 Python 中有许多这样的字符串,它们实际上是树表示。我想为每个单词提取父节点和子节点,例如对于'Hello',我想要(INTJ, UH),对于'My',它是(NP, PRP$)

这是我想要的结果:

(INTJ, UH) , (NP, PRP$), (NP, NN) , (VP, VBZ) , (VP , VPZ) , (ADJP, JJ) , (WHNP, WP), (SQ, VBZ), (NP, PRP$), (NP, NN)

我该怎么做?

【问题讨论】:

  • 那么你的数据结构是sentences。如果您不明白如何从那里获得在我的回答中使用该解决方案的能力,您需要提出一个新问题。
  • link 提出了新问题。非常感谢您帮助我@Zero
  • @rombi 这很好,但是请从这里删除部分新问题!谢谢。

标签: python tree extract nltk


【解决方案1】:

您的字符串显然是Tree 对象列表的表示。如果您可以访问或可以以其他方式重建该列表,那就更好了 - 如果没有,创建您可以使用的数据结构的最直接方法是eval()(所有usual caveats对用户提供的数据调用eval())。

由于您没有提及您的 Tree 课程,因此我将编写一个足以解决此问题的简单内容:

class Tree:

    def __init__(self, name, branches):
        self.name = name
        self.branches = branches

现在我们可以重新创建您的数据结构:

data = eval("""[Tree('ROOT', [Tree('S', [Tree('INTJ', [Tree('UH', ['Hello'])]), Tree(',', [',']), Tree('NP', [Tree('PRP$', ['My']), Tree('NN', ['name'])]), Tree('VP', [Tree('VBZ', ['is']), Tree('ADJP', [Tree('JJ', ['Melroy'])])]), Tree('.', ['.'])])]), Tree('ROOT', [Tree('SBARQ', [Tree('WHNP', [Tree('WP', ['What'])]), Tree('SQ', [Tree('VBZ', ['is']), Tree('NP', [Tree('PRP$', ['your']), Tree('NN', ['name'])])]), Tree('.', ['?'])])])]""")

一旦我们有了它,我们就可以编写一个函数来生成您想要的 2 元组列表:

def tails(items, path=()):
    for item in items:
        if isinstance(item, Tree):
            if item.name in {".", ","}:  # ignore punctuation
                continue
            for result in tails(item.branches, path + (item.name,)):
                yield result
        else:
            yield path[-2:]

此函数递归地下降到树中,每次遇到适当的叶节点时都会产生最后两个 Tree 名称。

使用示例:

>>> list(tails(data))
[('INTJ', 'UH'), ('NP', 'PRP$'), ('NP', 'NN'), ('VP', 'VBZ'), ('ADJP', 'JJ'), ('WHNP', 'WP'), ('SQ', 'VBZ'), ('NP', 'PRP$'), ('NP', 'NN')]

【讨论】:

  • tails 函数的第 6 行出现错误。我认为关键字from 不是必需的。其次,当我运行代码 print list(tails(data)) 时,它给了我这个[<generator object tails at 0x043CA918>, <generator object tails at 0x043CA940>] 。请帮帮我。
  • 啊,那么您使用的 Python 版本低于 3.3。让我更新代码...
  • @rombi 我已经更新了代码,因此它不再依赖 Python 3.3 中的 yield from 构造 introduced - 希望它现在对你有用。
  • 我在一个非常大的字符串上使用 eval。我收到此错误。 s_push: parser stack overflow Traceback (most recent call last): File "stanford.py", line 146, in <module> main() File "stanford.py", line 143, in main get_file() File "stanford.py", line 55, in get_file data = eval(str(val)) .任何解决此错误的解决方法@Zero
  • 来自我的回答:“如果您能够访问或以其他方式重建该列表会更好”。使用eval() 是最后的手段(我只使用它是因为您没有在问题中提供数据结构);由于该字符串是现有数据结构的表示,因此您应该改用该数据结构。在一个足够复杂的表示上调用eval() 给你一个堆栈溢出错误显然是一个糟糕的主意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多