在Python中重新调用函数(递归)与使用while语句

在Python中重新调用函数(递归)与使用while语句,python,recursion,while-loop,Python,Recursion,While Loop,好的,我知道可以使用while语句让程序在特定条件为真时保持运行。但是,仅在下面的或条件下调用函数是不正确的还是不好的做法 def ask(): me = input("What is your name? ") if me == "Tom": print("Hi, Tom!") else: print ("Who are you?") ask() 这似乎是“while语句”的一个更简单、简捷的版本,但我在Python教

好的,我知道可以使用while语句让程序在特定条件为真时保持运行。但是,仅在下面的条件下调用函数是不正确的还是不好的做法

def ask():
    me = input("What is your name? ")

    if me == "Tom":
        print("Hi, Tom!")
    else:
        print ("Who are you?")
        ask()

这似乎是“while语句”的一个更简单、简捷的版本,但我在Python教程中还没有见过这样执行的程序。

说实话,它们都“起作用”,这取决于您的用户情况。当然,与出现问题的情况相比,您更可能遇到递归深度,尽管它们都获得了类似的结果。实际上,使用while循环更简单,而且在我看来(在本例中)更像pythonic。(为什么要把它弄得更复杂?

你说速记?与之相比:

def ask():
    while input("What is your name? ") != "Tom":
        print ("Who are you?")
    print("Hi, Tom!")

我建议使用while语句,因为当ask函数有上限尝试输入和返回结果值时,您会感到困难

为了添加这些功能,我修改了此功能,例如:

def ask(count):
    if count < 0:
        return False

    me = input("What is your name? ")

    if me == "Tom":
        print("Hi, Tom!")
        return True
    else:
        print ("Who are you?")
        return ask(count - 1)
def ask(计数):
如果计数小于0:
返回错误
me=输入(“你叫什么名字?”)
如果我==“汤姆”:
打印(“嗨,汤姆!”)
返回真值
其他:
打印(“你是谁?”)
返回询问(计数-1)
这种实现是否如此复杂和混乱

如果ask函数是使用“while”语句实现的,那么修改就更简单了。
只需将“while”改为“to”,用上限设置循环并插入“返回”语句。

< P>我不认为这是坏的做法,除非您期望成百上千个递归调用,或者如果内存管理对您的特定应用程序很重要。

如其他答案所述,Python不支持尾部递归消除,这意味着对同一函数的递归调用不必向堆栈中添加新的堆栈帧。这样可以避免浪费不必要的内存


有关为什么Python的创建者Guido认为尾部递归消除是非Python的有趣阅读,请参阅:

它们是不同的。由于Python不执行尾部递归,因此重新调用函数将(最终)爆发。但是,我认为示例代码/书籍/教程试图展示递归的概念——这在Python中不是一个好的示例:)在许多情况下,使用递归可以极大地简化问题,例如使用通用合并排序、快速排序或二叉树查找。(但退化的快速排序可能并不理想;-)谢谢。我甚至不知道我想做什么,但我有一个名字。但是现在我有一些东西要查找(尾部递归),我一定会尝试更好地理解它,最重要的是,避免它。谢谢:)当你需要的时候,尾部递归会是一件令人惊奇的事情。但是你必须知道什么时候需要它。从技术上讲,Python确实做了尾部递归:如果它不做,这个函数就根本不起作用。它没有做的是尾部调用优化。请参阅以了解更多信息。请尝试将代码放在函数末尾以查看两者之间的差异。老实说,这有点混乱?以后如何返回输入?请使用
raw\u input
。雅各布:好吧,只是证明它可以简洁。杰瑞的例子使用了一个明确的“汤姆”,我的例子也是如此;返回显式输入并不困难。(还要指出力求简洁的自然结论——最初的递归示例也相当混乱)dancek:显然他使用的是python 3,所以实际上正确的函数是input()