我是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)
我很欣赏一些如何实现结果的提示。提前谢谢。
答案 0 :(得分:2)
您的问题是您在某些情况下返回字符串,并在其他情况下打印列表。确保你的替换者总是返回一个字符串列表,你应该没问题。
答案 1 :(得分: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)
答案 2 :(得分: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)
如果对树[1:]进行更改,则实际上并未对列表进行更改,而是对拼接进行更改。所以enumerate函数可以解决这个问题。您的sub="_REPLACE_"
实际上并未更改列表。它只是为名称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', '.']