2012-03-13 56 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