2015-07-11 98 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)的标准比较。 –