2013-03-31 56 views
2

我是Python新手,遇到了一个我无法解决的问题。JSON,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

@Daniel Roseman感谢您的编辑! – Serge

回答

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', '.']