为什么我的递归函数返回 None?

Why does my recursive function return None?

提问人:Cate 提问时间:7/22/2013 最后编辑:GeorgyCate 更新时间:4/29/2023 访问量:131149

问:

我有这个函数来调用自己:

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

但是,如果我输入其他内容,然后输入“a”或“b”,我会得到这个:

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

我不知道为什么要返回,因为它应该只返回.这是从哪里来的,我该如何修复我的功能?get_input()Nonemy_varNone

Python 函数 递归 返回

评论

19赞 Gustav Larsson 7/22/2013
递归调用它时需要这样做。return Dat_Function()
8赞 gonz 5/18/2016
只是一个提示:这种情况的惯用方式是my_var != "a" and my_var != "b"my_var not in ('a', 'b')
1赞 ggorlen 4/29/2021
@gonz不一定。现在,您正在分配一个元组,只是为了进行简单的比较。在关键路径上可能会很痛苦,而且它的可读性并不高,真的。
2赞 Karl Knechtel 8/13/2022
这是一个用于演示目的的递归的简单示例;但是,如果您确实需要执行此任务,则循环更有意义。请参阅要求用户输入,直到他们给出有效的响应while
0赞 Karl Knechtel 12/2/2022
有时,人们在尝试将迭代和递归结合起来时会遇到这个问题。如果循环中有递归调用,则可能不清楚如何处理结果 - 因为会跳出循环。但是,一般来说,这与尝试调用任何其他函数而不是使用递归是相同的问题。这也是一个常见问题,这里有一个重复的引用:如何使用 return 从循环中取回多个值?我可以把它们放在一个列表中吗?return

答:

143赞 roippi 7/22/2013 #1

它之所以返回,是因为当您递归调用它时:None

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

..您不返回该值。

因此,当递归确实发生时,返回值会被丢弃,然后你就会从函数的末尾掉下来。从函数的末尾掉下来意味着 python 隐式返回 ,就像这样:None

>>> def f(x):
...     pass
>>> print(f(20))
None

因此,您不仅需要调用语句,还需要递归调用返回的内容:get_input()ifreturn

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

评论

0赞 Cate 7/22/2013
如果以递归方式调用 if 语句,它不应该再次运行吗?我不明白为什么它不会返回值。
1赞 roippi 7/22/2013
不。看我的编辑。递归发生,然后你丢弃递归返回的内容。
1赞 roippi 7/22/2013
你把我弄丢了......你可以失败多少次,但“成功”的那个将返回,这将通过所有递归调用一直传递给原始调用者。是的,是.main()my_varreturnmain()
3赞 Baimyrza Shamyr 4/24/2016
对递归函数使用 return 将其值放入堆栈中,以便当函数执行递归时,堆栈中的递归值会逐个获取。如果不使用 return ,堆栈将仅收集 “None” 值。
1赞 jouell 6/11/2019
先生,您是个天才!这对我来说并不直观。
13赞 Simon 7/22/2013 #2

若要返回 None 以外的值,需要使用 return 语句。

在您的例子中,if 块仅在执行一个分支时执行返回。要么将返回值移到 if/else 块之外,要么在两个选项中都有返回值。

评论

0赞 Cate 7/22/2013
我试过把它移出街区,但无济于事。它不是返回正确的值,而是返回第一个不正确的值。此外,我不想要 if/else 语句的 if 部分的返回语句,因为我希望函数只返回正确的值。
0赞 ocramz 7/15/2023
这个语言“功能”绊倒了我好几天。作为一个函数式程序员,我觉得这非常违反直觉
2赞 user6348168 5/18/2016 #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())
0赞 Oghli 4/29/2023 #4

我认为要更多地了解递归函数中的实际情况,您应该尝试调试代码。我推荐一个有趣的可视化代码执行工具,称为 Python Turor

我将在您的递归函数上尝试此测试用例,并可视化执行过程:

首先输入 as,然后输入 as 。my_varxmy_vara

您可以从调试可视化工具中看到它何时执行 return 语句。my_var = a

enter image description here

然后递归函数将返回递归函数中这一行代码处的输入值。a

enter image description here

之后,它将再次执行函数,它不会返回任何值,这就是最终值为 .get_input()print('got input:', get_input())None

enter image description here

如果递归函数中的替换调用 It 将返回此测试用例中的值。get_input()return get_input()my_vara

enter image description here

希望这个使用 Python Tutor 调试可视化工具的演示有助于阐明递归函数的执行过程。