Python 树字符串到括号字符串

Python 树字符串到括号字符串,python,tree,nltk,Python,Tree,Nltk,假设我有一个句子的树字符串: s = "(TOP (S (NP-TMP (NP (DT This) (NN time)) (ADVP (RP around))) (NP-SBJ (PRP they)) (VP (VBP 're) (VP (VBG moving) (ADVP (RB even) (RBR faster))))))" 我想将其转换为一个括号结构,如下所示: "(((This time)(around))(they)(('re)((moving)(e

假设我有一个句子的树字符串:

s = "(TOP (S (NP-TMP (NP (DT This) (NN time)) (ADVP (RP around))) (NP-SBJ (PRP they)) (VP (VBP 're) (VP (VBG moving) (ADVP (RB even) (RBR faster))))))"

我想将其转换为一个括号结构,如下所示:

"(((This time)(around))(they)(('re)((moving)(even faster))))"
(moving (even faster))
我试着做到以下几点:

import nltk

s = "(TOP (S (NP-TMP (NP (DT This) (NN time)) (ADVP (RP around))) (NP-SBJ (PRP they)) (VP (VBP 're) (VP (VBG moving) (ADVP (RB even) (RBR faster))))))"
tree = nltk.Tree.fromstring(s)

out = "("
for subtrees in tree:
    # there are threee subtrees
    # print(len(subtree))
    for i, subtree in enumerate(subtrees):
        if len(subtree) > 1:
            out += "("
        for bracketing in range(len(subtree)):
            # print(subtree[bracketing])
            flattened_tree = subtree[bracketing].flatten()
            flattened_string = str(flattened_tree)
            flattened_string = flattened_string.replace(flattened_tree.label() + " ", "")
            print(flattened_string)
            out += flattened_string
        if len(subtree) > 1:
            out += ")"
        # break
out += ")"

print(out)
# (((This time)(around))(they)(('re)(moving even faster)))
编辑:

如果您看到,
“This”
“time”
是同一父级的一部分,
“NP”
。因此,它们成为连续的成分,即
(这次)

然而,
“around”
是单个单词的组成部分,尽管它是同一左子树的一部分。因此,它变成了
((这次)(大约))

类似地,对于右子树-
“'re”
“'moving ever”
,我们看到
“moving”
“ever ever ever”
共享同一个父树,
“VP”


因此,它变成了,
(('re)((移动)(甚至更快))

如果我理解正确的话,当原子字符串有一个不是原子字符串但已经是带括号的组合的同级字符串时,您希望将括号添加到原子字符串中,这样您就永远不会有这样的模式:

"(((This time)(around))(they)(('re)((moving)(even faster))))"
(moving (even faster))
或者换句话说,空格只能是两个原子字符串之间的分隔符

我将在两个递归过程中完成此操作:

  • 第一个将树转换为嵌套列表的规则。这将更容易区分上述规则

  • 第二步,将嵌套列表转换为带括号的最终字符串

代码:

导入nltk
def tolist(树):
如果isinstance(树[0],str):
返回树[0]
res=[tolist(子树)表示树中的子树]
叶子=总和(子对象在res中的isinstance(子对象,str))
如果0
请提供预期结果。显示中间结果与预期结果之间的差异。我们应该能够将单个代码块粘贴到文件中,运行它,并重现您的问题。这还可以让我们在您的上下文中测试任何建议。您发布的代码不是最小的;您的问题似乎与NLTK无关;您中的一些人r代码的存在只是为了将缺少的输入从NLTK转换为字符串,并且您至少有一个未定义的符号。您忽略了提供诊断跟踪--您的代码在哪里删除了所需的括号(此处没有括号)?对于初学者来说,这似乎是一个简单的递归例程而不是循环的简单例子。清理一下,这样我们就可以帮助跟踪和诊断。我提供了一个完整的工作示例。您是否尝试过运行脚本?通过将树结构转换为原始字符串,我正在用空字符串替换某些标签。希望可以现在更清楚了。例如,如果你看到,“This”和“time”是同一个父级“NP”的一部分。因此,它们成为连续的成分,即(这次)。然而,“around”是一个单词成分,虽然是同一个左子树的一部分。因此,它变成了((这次)(around))。同样,对于右子树-“'re”和“‘走得更快’,我们看到‘走得更快’和‘走得更快’是同一个父项“VP”。因此,它变成了,((re)((走得)(更快))。我希望这个解释是清楚的。从我的理解来看,“走得更快”、“甚至”、“更快”是同一个父项“VP”的一部分。因此,我认为它变成了((走得)(走得更快))因为它们现在被视为一个整体。所以,这些词之间有一个共同的外括号。@nikinlpds:如果我错了,请纠正我。