2013-04-18 2 views
2

Я пытаюсь написать рекурсивную функцию Python 3, которая сообщит мне, является ли целое число во вложенном списке. Я не уверен, как я могу вернуть код True, если он найдет его в списке, и False, если он не найдет его в списке. Когда я распечатать результат моего для цикла я получаю кучуРекурсия Python, почему моя функция не работает?

false 
false 
false 
false 
true 
false 
false 
false 

и т.д. Но, она возвращает значение False, потому что последний вызов был ложным, даже если я хочу, чтобы вернуться верно. Как я могу это исправить?

Вот мой код:

def nestedListContains(NL, target):  
    if(isinstance(NL, int)): 
     return NL  

    for i in range(0, len(NL)): 
     return (nestedListContains(NL[i], target) == target) 

    return False 

А вот как я называю это

print(nestedListContains([[3], [4,5,7], [[[8]]]], 8)) 

EDIT: Это, кажется, работает для меня, но это кажется довольно Гетто:

def nestedListContains(NL, target):  
    if(isinstance(NL, int)): 
     if(NL == target): 
      return 1 
     return 0 

    x = 0 

    for n in NL: 
     x += nestedListContains(n, target) == 1   

    return x != 0 
+0

Помимо рекурсивных проблем, ваш базовый случай кажется неправильным. Когда вы переходите к 'int', вместо того, чтобы возвращать true, если он равен цели, вы возвращаете' int'. Это означает, что в конечном итоге вы вернете true, если в списке есть ненулевые элементы, иначе false. – abarnert

+0

Вы также можете подумать о надежности. Если NL содержит любые non-int non-sequence, он поднимет 'TypeError', что, вероятно, прекрасно, но если оно содержит любые строки, оно перейдет в бесконечную рекурсию (которая в конечном итоге вызовет исключение, лимит), что может быть неудобно. – abarnert

+0

Также: Почему бы просто не удалить проверку 'int', а просто« if NL == target: return True »? Если 'target' всегда является' int', это будет иметь тот же эффект. Но он позволяет вам искать другие типы (в том числе объекты, которые могут сравниваться с «int», но не одни). И это проще. – abarnert

ответ

4

Вы получили return результат независимо от того, является ли он True или нет. Вы могли бы сделать что-то вроде этого:

def nestedListContains(NL, target):  
    if isinstance(NL, int): 
     return NL == target 

    for n in NL: 
     result = nestedListContains(n, target) 

     if result: 
      return result 

    return False 
+1

Вы имели в виду 'nestedListContains (n, target) == target'? –

+0

@LevLevitsky: Да, спасибо. – Blender

+0

Защиту nestedListContains (NL, цель): , если (isinstance (NL, Int)): , если (NL == цель): возврата 1 возврата 0 х = 0 для п в NL: х + = nestedListContains (n, target) == 1 return x! = 0 Ваш метод все еще не работал для меня Теперь я делаю вещи в гетто, но, похоже, это работает, есть ли альтернатива этому ? – Jason

5

Моей попытки:

def contains(lst, target): 
    if isinstance(lst, int): 
     return lst == target 

    return any(contains(x, target) for x in lst) 
0

Использования утиной типизации для решения @ Gatto в

def contains(lst, target): 
    try: 
     return any(contains(x, target) for x in lst)   
    except TypeError: 
     return lst == target 
+1

Может возникнуть бесконечная рекурсия, если 'lst' имеет строку. Я думаю, что лучше проверить, есть ли атрибут '__iter__'. – gatto

+0

очень верно, спасибо за добавление проницательности. – dansalmo

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