2015-07-11 3 views
0

Моя функция same_num принимает значения, которые являются общими для обоих отсортированных списков, и добавляет их в «результат». Он использует рекурсию и два смещения, pos1 и pos2, которые всегда изначально установлены в 0, для сравнения значений в списке. При запуске функции он работает отлично в первый раз, однако, если я запустил функцию во второй раз, исходный результат добавляется с ответом, который я получил от его запуска. Где я иду не так?Выходной список Дублирующие значения

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

При запуске функции он работает нормально в первый раз, однако если I запускает функцию во второй раз, исходный результат добавляется с ответом, который я получил от его запуска.

Это точная проблема. Вы не опорожняете предыдущий result, прежде чем вы его вызовете снова. result по-прежнему содержит значения при первом запуске функции.

Например, попробуйте запустить его, как это вместо:

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! Вы добавляете материал в result (result.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

Почему 'Нет' лучше, чем' [] '? Ссылка означает «Нет», как правило, хороший выбор, но не дает объяснений, почему. – dmlittle

+0

@ mista619, обязательно. Если 'result' - локальная переменная, то она не будет сохранена в рекурсивных вызовах. Вот почему я добавил его как дополнительный (необязательный) параметр в функцию для рекурсивного вызова. Сравните это со стандартной [рекурсивной реализацией QuickSort] (https://en.wikipedia.org/wiki/Quicksort#Algorithm). –

Смежные вопросы