2012-03-13 58 views
1

我写这样的功能:问题与递归调用

def append_to_all(L, v): 
    '''Append value v, which may be of any type, to all the nested lists in L. 
    L is a list, and may contain other lists.''' 

     if len(L) == 0: 
      return L.append(v) 
     elif isinstance(L[0], list): 
      L[0].append(v) 
      return append_to_all(L[1:], v) 
     else: 
      return append_to_all(L[1:], v) 

if __name__ == '__main__': 
    L = [1, 2, [3]] 
    append_to_all(L, 'a') 
    print L # should return [1, 2, [3, 'a'], 'a'] 

该函数返回[1,2,[3, '一个']]代替[1,2,[3, 'A'], '一个']。我尝试过调试,但无法找出错误。我看起来当len(L)== 0函数被调用时,'a'被追加到空列表中,但不是全局L.

我该如何解决这个问题?

谢谢!

回答

3

L[1:]产生列表的副本。它是一个全新的列表,其中包含除第一个项目之外的原始列表中的所有内容。如果向其中添加元素,那对原始列表没有任何影响。因此,当你追加到空列表时,它只附加到空列表中,而不是附加在它之前的任何列表。

为了做到这一点递归你不应该追加到列表中,而你应该返回新的列表

def append_to_all(L, v): 
'''Append value v, which may be of any type, to all the nested lists in L. 
L is a list, and may contain other lists.''' 

    if len(L) == 0: 
     return [v] 
    elif isinstance(L[0], list): 
     return [L[0] + [v]] + append_to_all(L[1:], v) 
    else: 
     return [L[0]] + append_to_all(L[1:], v) 

但是,这是不是真的使用递归的地方。迭代解决方案更简单,更高效。

def append_to_all(L, v): 
    for item in L: 
     if isinstance(L, list): 
      item.append(v) 
    L.append(v) 
+0

啊!得到它了!谢谢! – isal 2012-03-13 05:00:20