2015-07-11 102 views
0

我的函數same_num使用兩個排序列表共有的值,並將它們附加到'result'上。它使用遞歸和兩個偏移量,即始終設置爲0的pos1和pos2來比較列表中的值。當運行該函數時,它第一次運行正常,但是如果我第二次運行該函數,原始結果會附加我最初運行它的答案。我哪裏錯了?輸出列表重複值

result=[] 

def same_num(list1,list2,pos1,pos2): 
    list1=sorted(list1) 
    list2=sorted(list2) 

    if pos1==len(list1) or pos2==len(list2): 
     return result 
    if list1[pos1]==list2[pos2]: 
     result.append(list1[pos1]) 
     return same_num(list1,list2,pos1+1,pos2+1)  
    if list1[pos1]>list2[pos2]: 
     return same_num(list1,list2,pos1,pos2+1) 
    if list1[pos1]<list2[pos2]: 
     return same_num(list1,list2,pos1+1,pos2) 

例如:

same_num([3,1,2,4],[3,1,2,4,5,6],0,0)=>[1,2,3,4] 

重新運行在外殼前面的示例生產:

same_num([3,1,2,4],[3,1,2,4,5,6],0,0)=>[1, 2, 3, 4, 1, 2, 3, 4] 

當它仍然應該產生:

[1,2,3,4] 
+1

你是否每次運行函數都將結果重置爲空列表? – user3636636

回答

0

當運行該功能時,它在第一次運行良好,但是如果我第二次運行該功能,原始結果會附加 我最初運行它的答案。

這是確切的問題。在再次調用之前,您沒有清空以前的resultresult仍包含您第一次運行該功能時的值。

例如,嘗試這樣的,而不是運行它:

output = same_num([3,1,2,4],[3,1,2,4,5,6],0,0) 
print output 
result = [] 
output = same_num([3,1,2,4],[3,1,2,4,5,6],0,0) 
print output 

兩個輸出將是[1,2,3,4]

2

的問題是,result是一個全局變量。 Globals are bad!您正在向resultresult.append(...))添加內容,但在第一次調用same_num函數之後從未清除它。

(雖然我能明白你爲什麼要採取這種方式,因爲在概念上它往往更容易使用全局變量接近遞歸函數)。

如果您result可以傳遞給same_num函數的參數遞歸調用相同的函數...此問題已修復。

def same_num(list1,list2,pos1,pos2,init_result=None): 
    # IMPORTANT: see remark below on why init_result=[] 
    # would not do what you expect 
    result = init_result if init_result is not None else [] 

    list1=sorted(list1) 
    list2=sorted(list2) 

    if pos1==len(list1) or pos2==len(list2): 
     return result 
    if list1[pos1]==list2[pos2]: 
     result.append(list1[pos1]) 
     return same_num(list1,list2,pos1+1,pos2+1,result)  
    if list1[pos1]>list2[pos2]: 
     return same_num(list1,list2,pos1,pos2+1,result) 
    if list1[pos1]<list2[pos2]: 
     return same_num(list1,list2,pos1+1,pos2,result) 

# multiple invocations will return the same (expected) result 
print(same_num([3,1,2,4],[3,1,2,4,5,6],0,0)) 
print(same_num([3,1,2,4],[3,1,2,4,5,6],0,0)) 

順便說一句,看到"Common Python Gotchas: Mutable default arguments"爲什麼我用init_result=None爲默認值,而不是init_result=[]

+0

我曾試着讓'result'成爲局部變量,但是任何時候我都會運行這個函數,它會輸出一個空的列表。 – mista619

+0

爲什麼'None'比'[]'好?鏈接狀態「無」通常是一個不錯的選擇,但沒有解釋爲什麼。當然是 – dmlittle

+0

@ mista619。如果'result'是一個局部變量,那麼它不會被保存在遞歸調用中。這就是爲什麼我將它作爲函數的附加(可選)參數添加的,以便進行遞歸調用。將此與[快速排序的遞歸實現](https://en.wikipedia.org/wiki/Quicksort#Algorithm)的標準比較。 –