Почему моя рекурсивная функция не возвращает ничего?

#python #recursion

Вопрос:

У меня есть эта функция, которая сама себя называет:

 def get_input():  my_var = input('Enter "a" or "b": ')   if my_var != "a" and my_var != "b":  print('You didn't type "a" or "b". Try again.')  get_input()  else:  return my_var  print('got input:', get_input())  

Теперь, если я введу только «a» или «b», все будет работать нормально:

 Type "a" or "b": a got input: a  

Но, если я наберу что-то другое, а затем «а» или «в», я получу это:

 Type "a" or "b": purple You didn't type "a" or "b". Try again. Type "a" or "b": a got input: None  

Я не знаю, почему get_input() возвращается None , так как он должен только возвращаться my_var . Откуда это None берется и как я могу исправить свою функцию?

Комментарии:

1. Вам нужно сделать return Dat_Function() это при рекурсивном вызове.

2. Просто совет: идиоматическим способом этого my_var != "a" and my_var != "b" условия было бы my_var not in ('a', 'b')

3. @гонз не обязательно. Теперь вы попадаете в кучу, выделяя кортеж только для простого сравнения. Это может быть болезненно на критическом пути, и на самом деле это не намного более читабельно.

Ответ №1:

Он возвращается None , потому что, когда вы рекурсивно вызываете его:

 if my_var != "a" and my_var != "b":  print('You didn't type "a" or "b". Try again.')  get_input()  

..вы не возвращаете значение.

Таким образом, пока рекурсия происходит, возвращаемое значение отбрасывается, и затем вы выпадаете из конца функции. Выпадение из конца функции означает , что python неявно возвращает None , точно так же, как это:

 gt;gt;gt; def f(x): ... pass gt;gt;gt; print(f(20)) None  

Итак, вместо того, чтобы просто позвонить get_input() в свое if заявление, вам нужно return это:

 if my_var != "a" and my_var != "b":  print('You didn't type "a" or "b". Try again.')  return get_input()  

Комментарии:

1. Не следует ли снова выполнить оператор if, если он вызывается рекурсивно? Я не понимаю, почему он не вернет значение.

2. Нет. Смотрите мою правку. Происходит рекурсия, а затем вы отбрасываете то, что возвращает рекурсия.

3. Ты потерял меня из-за этого main() кусочка… Вы можете терпеть неудачу столько раз, сколько захотите , вернется тот, который «преуспеет» my_var , который будет передан ( return ред.) через все рекурсивные вызовы вплоть до исходного вызывающего абонента. Что, да, так и есть main() .

4. Используйте return для рекурсивной функции , чтобы поместить ее значение в стек, чтобы, когда функция будет выполнять рекурсию, значения из стека принимались одно за другим. Если вы не используете return , стек будет собирать только значения «Нет».

5. вы, сэр, гений! Это не было для меня интуитивно понятным.

Ответ №2:

Чтобы вернуть значение, отличное от None, вам необходимо использовать оператор return.

В вашем случае блок if выполняет возврат только при выполнении одной ветви. Либо переместите возврат за пределы блока if/else, либо используйте возврат в обоих вариантах.

Комментарии:

1. Я пытался убрать его из блока, но безрезультатно. Вместо возврата правильного значения он возвращает первое неверное значение. Кроме того, мне не нужен оператор return для части if оператора if/else, потому что я хочу, чтобы функция возвращала только правильное значение.

Ответ №3:

 def get_input():  my_var = input('Enter "a" or "b": ')   if my_var != "a" and my_var != "b":  print('You didn't type "a" or "b". Try again.')  return get_input()  else:  return my_var  print('got input:', get_input())  

Ответ №4:

я думаю, что этот код более понятен

 def get_input():  my_var = str(input('Enter "a" or "b": '))  if my_var == "a" or my_var == "b":  print('got input:', my_var)  return my_var  else:  print('You didn't type "a" or "b". Try again.')  return get_input() get_input()  

Комментарии:

1. @SergeyShubin как вы думаете, чем этот код отличается от кода пользователя 6348168. Я чувствую, что и то, и другое-одно и то же.

2. @jiten код был изменен после моего комментария, поэтому он больше не актуален. Я думаю, что мне следует удалить его