2

我是 Python 新手,遇到了一个我无法解决的问题。

我已将以下解析树从 JSON 解码为以下列表。

>>> tree
['S', ['NP', ['DET', 'There']], ['S', ['VP', ['VERB', 'is'], ['VP', ['NP', ['DET', 'no'], ['NOUN', 'asbestos']], ['VP', ['PP', ['ADP', 'in'], ['NP', ['PRON', 'our'], ['NOUN', 'products']]], ['ADVP', ['ADV', 'now']]]]], ['.', '.']]]

使用递归函数,我已经能够获得包含终结词的列表。

def explorer(tree):
    for sub in tree[1:]:
        if(type(sub) == str):
            allwords.append(sub)
        else:
            explorer(sub)

>>> allwords
['There', 'is', 'no', 'asbestos', 'in', 'our', 'products', 'no'.]

现在我需要替换原始树中符合某些条件的单词,以便得到如下内容:

['S', ['NP', ['DET', 'There']], ['S', ['VP', ['VERB', 'is'], ['VP', ['NP', ['DET', 'no'], ['NOUN', '_REPLACED_']], ['VP', ['PP', ['ADP', 'in'], ['NP', ['PRON', 'our'], ['NOUN', 'products']]], ['ADVP', ['ADV', 'now']]]]], ['.', '.']]]

我尝试了以下功能,但我无法向上传播替换,所以我总是得到相同的旧原始树。

def replacer(tree):
    string=[]
    for sub in tree[1:]:
        if(type(sub) == str):
            if #'condition is true':
                sub="_REPLACE_"
                return sub
            else: return sub    
        else:
            string.extend(replacer(sub))
    print(string)     

我将不胜感激有关如何实现结果的一些提示。先感谢您。

4

3 回答 3

2

您的问题是在某些情况下您正在重新调整字符串,并在其他情况下打印列表。确保你的替换器总是返回一个字符串列表,你应该没问题。

于 2013-03-31T15:09:06.983 回答
2

所以这是一个我如何使用列表推导来做这类事情的例子。如果您不知道,列表推导是something = [explorer(x) for x in something]. 这也是递归发生的地方。你得到的是一个完全相同结构的列表,但是你已经“去过”每个端点并且可以检查和替换东西。我做了几个任意替换。

>>> tree = ['S', ['NP', ['DET', 'There']], ['S', ['VP', ['VERB', 'is'], ['VP', ['NP', ['DET', 'no'], ['NOUN', 'asbestos']], ['VP', ['PP', ['ADP', 'in'], ['NP', ['PRON', 'our'], ['NOUN', 'products']]], ['ADVP', ['ADV', 'now']]]]], ['.', '.']]]
>>> def explorer(something):
        if type(something) == list:
            something = [explorer(x) for x in something]
        else:   # You may want to check other conditions here, like if it's a string
            if something == 'asbestos':
                something = 'Oh my'
            if something == 'S':
                something = 'Z'
        return something

>>> explorer(tree)
['Z', ['NP', ['DET', 'There']], ['Z', ['VP', ['VERB', 'is'], ['VP', ['NP', ['DET', 'no'], ['NOUN', 'Oh my']], ['VP', ['PP', ['ADP', 'in'], ['NP', ['PRON', 'our'], ['NOUN', 'products']]], ['ADVP', ['ADV', 'now']]]]], ['.', '.']]]
>>> 

我只是在更仔细地阅读了你的话后注意到了一些事情。您无法“向上传播替换”的原因是您的循环结构如下:

for x in aList:
    if x = somethingSpecial:
        x = somethingElse

这在 Python 中不起作用,但这样做:

for i,x in enumerate(aList):
    if x = somethingSpecial:
        aList[i] = somethingElse

现在aList已经按照您想要的方式进行了修改。如果您不知道做什么enumerate(),只需复制/粘贴:

aList = ['a','b','c']
for i,x in enumerate(aList):
    print(i,x)
于 2013-03-31T15:40:16.873 回答
1

如果我正确理解您的问题,解决您的问题的一种方法是:

 >>> tree = ['S', ['NP', ['DET', 'There']], ['S', ['VP', ['VERB', 'is'], ['VP', ['NP', ['DET', 'no'], ['NOUN', 'asbestos']], ['VP', ['PP', ['ADP', 'in'], ['NP', ['PRON', 'our'], ['NOUN', 'products']]], ['ADVP', ['ADV', 'now']]]]], ['.', '.']]]
 >>> def replacer(tree):
        for i, sub in enumerate(tree[1:]):
            if type(sub) == str and sub == 'asbestos':
                tree[i+1] = '__REPLACE__'
            else:
                replacer(sub)

如果您对 tree[1:] 进行更改,您实际上并没有对列表进行更改,而是对拼接进行了更改。因此enumerate函数可以帮助您解决这个问题。您sub="_REPLACE_"实际上并没有更改列表。它只是为 name 分配一个新值sub

结果:

>>> replacer(tree)
>>> tree
['S', ['NP', ['DET', 'There']], ['S', ['VP', ['VERB', 'is'], ['VP', ['NP', ['DET', 'no'], ['NOUN', '__REPLACE__']], ['VP', ['PP', ['ADP', 'in'], ['NP', ['PRON', 'our'], ['NOUN', 'products']]], ['ADVP', ['ADV', 'now']]]]], ['.', '.']]]

要获得像您的第一个函数创建的新列表,您可以简单地将您的第一个函数应用于新tree列表:

>>> explorer(tree)
['There', 'is', 'no', '__REPLACE__', 'in', 'our', 'products', 'now', '.']
于 2013-03-31T15:16:43.883 回答