2015-12-11 4 views
1

Я написал функцию bisect, которая принимает список слов «t» и слово «val». Он рекурсивно уменьшает список до тех пор, пока индекс списка не станет словом или не вернет false. Если он найдет слово, он должен вернуть его.Возвращаемое значение Python

Я прочитал несколько книг, документацию и все применимые вопросы здесь, но я все еще не могу определить, что я делаю неправильно: почему функция не вернет значение? Он напечатает значение просто отлично, но не будет возврата, кроме None.

Любая помощь очень ценится!

def bisect(t, val): 
    if t[len(t)/2] < val and len(t) > 1: 
     t = t[len(t)/2:] 
     bisect(t, val) 
    elif t[len(t)/2] > val and len(t) > 1: 
     t = t[:len(t)/2] 
     bisect(t, val) 
    elif t[len(t)/2] == val: 
     t = t[len(t)/2] 
     #print type(t), t 
     return t 
    else: 
     return False 

b = make_list(t) 
x = bisect(b, 'and') 
print x 
+0

Вы уверены, что не хотите возвращать bisect (..) 'при выполнении рекурсивных вызовов? – ThiefMaster

+0

Если я поставил оператор печати после 'if' и первого' elif', он правильно печатает (половину) список, пока не найдет значение. Правильно ли я понимаю ваш вопрос? – Sumtingwong

ответ

0

Эта модифицированная версия работает:

def bisect(t, val): 
    mid = len(t)//2 
    mid_ele = t[mid] 
    end = len(t) 
    if mid_ele < val and end > 1: 
     t = t[mid:] 
     return bisect(t, val) 
    elif mid_ele > val and end > 1: 
     t = t[:mid] 
     return bisect(t, val) 
    elif mid_ele == val: 
     t = mid_ele 
     return t 
    else: 
     return False 

b = ['she', 'he', 'you', 'and', 'me'] 
print(bisect(b, 'and')) 

печатает желаемое:

and 

Я сделал это Python 3 доказательство с использованием // для целочисленного деления и добавлены два returns перед рекурсивным вызовом.

+0

Понял. И мои извинения: 'б = make_list (т)' называет это: 'T = открыт ('list.txt')' определение функции make_list (т): '' а = [] '' для строка в t: ' ' word = line.strip() ' ' a.append (word) ' ' return a' Этот список отлично печатается при вызове 'b'. – Sumtingwong

+0

Удивительный, спасибо. Я добираюсь туда ... – Sumtingwong

1

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

def main(): 
    b = ['a', 'able', 'ability', 'abort', 'and', 'arc', 'zygote'] 
    x = bisect(b, 'and') 
    print x 



def bisect(t, val): 
    if t[len(t)/2] < val and len(t) > 1: 
     t = t[len(t)/2:] 
     t = bisect(t, val) 
    elif t[len(t)/2] > val and len(t) > 1: 
     t = t[:len(t)/2] 
     t = bisect(t, val) 
    elif t[len(t)/2] == val: 
     t = t[len(t)/2] 
     print type(t), t 
    else: 
     return False 

    return t 

if __name__ == '__main__': 
    main() 

Первый раз Bisect называется, т устанавливается в ['abort', 'and', 'arc', 'zygote']. При втором вызове для деления пополам t устанавливается на ['abort', 'and'] На третьем вызове мы находим 'and' и возвращаем это значение.

ЕСЛИ вы вернулись, как вы были (только вернувшись из точного совпадения или ложного результата), то вы вернетесь ко второму вызову (['abort', 'and']), то первый вызов (['abort', 'and', 'arc', 'zygote']), и, наконец, вы вернетесь без удара a return t в этом первом звонке. Таким образом, ничего не возвращается.

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

Надеюсь, это очистит ваш вопрос.

+0

Существует один тривиальный случай. Если ваш исходный пример имел целевое слово в точной середине списка, то он вернул бы матч правильно. –

+0

Удивительный, имеет смысл и большое спасибо! – Sumtingwong

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