while循环更改变量[python]中的递归函数

时间:2018-01-02 16:31:30

标签: python recursion while-loop

我让学生给我以下代码:

def addtwo():
 numb=input("enter any number")
 add=int(numb)+2
 print(add)
 inp = input("do you wish to enter again")
 while inp=="yes":
       addtwo()

在第一次迭代之后,如果用户输入除“是”之外的任何内容,则while循环的主体不会按预期执行。但是如果我们输入“是”,它会执行(再次,如预期的那样)并提示"输入任何数字",但在第二次迭代中,即使用户输入除#以外的任何内容39;是'在"你想再次输入",while循环STILL的主体执行。现在我在其上运行调试器,发现inp的值在执行第5行时只更改为'yes'。在执行行之前,inp的值,根据调试器仍然是用户输入的内容。为什么会这样?

现在我在这里查了一下,但是找不到任何解释,虽然我找到了一种解决方法,在while循环体内调用addtwo()之前添加一个返回值(我在这里找到了它:Calling a function recursively for user input)但是无法理解为什么inp的值只是在本地堆栈中发生变化,以及return语句如何修复它?

这是工作代码:

def addtwo():
     numb=input("enter any number")
     add=int(numb)+2
     print(add)
     inp = input("do you wish to enter again")
     while inp=="yes":
           return addtwo()

而且,为了添加我的谜题,如果我们使用if语句而不是while,代码就可以正常工作。

2 个答案:

答案 0 :(得分:3)

<强>摘要

这是因为一旦你输入了yes,那么无论下一次递归调用是什么,该函数都将永远循环。

您可以通过更改以下内容来修复代码:

while inp == "yes":
    add_two()

if inp == "yes":
    add_two()

浏览

  • add_two被称为
  • 用户输入数字
  • 他们被问到是否愿意继续
  • 他们进入&#34;是&#34;
  • 而imp ==&#34;是&#34;现在永远是真的
  • 它调用add_two
    • 他们输入一个数字
    • 他们输入&#34; no&#34;
    • 循环没有运行,所以返回第一次调用add_two
  • 回到while循环。它仍然评估为true,因此继续调用add_two

退货声明

默认情况下,在python中,不返回任何内容的函数实际上返回None。这意味着你调用add_two,如果用户没有输入&#34; yes&#34;当提示时,它将返回,这将强制第一次调用也返回。

答案 1 :(得分:1)

调用递归函数有点像是在那里复制并粘贴了内部函数。复制/粘贴和真正的递归之间存在一些差异:

  • 每个函数都有自己的一组变量
  • 当您将一个函数复制并粘贴到自身时,该函数只能在粘贴时多次调用(副本),而递归会自动深入地进行。 (这就是递归的全部要点。)

尽管存在这些差异,如果您正在努力理解递归调用,复制和粘贴是一种思考它的好方法。让我们试试你的功能吧。以下代码等同于您编写的内容,只要您不多次输入“yes”:

def addtwo0():
     numb=input("enter any number")
     add=int(numb)+2
     print(add)
     inp = input("do you wish to enter again")
     while inp=="yes":
           return addtwo1()

def addtwo1():
     numb=input("enter any number")
     add=int(numb)+2
     print(add)
     inp = input("do you wish to enter again")
     while inp=="yes":
           return addtwo2()

def addtwo2():
     numb=input("enter any number")
     add=int(numb)+2
     print(add)
     inp = input("do you wish to enter again")
     while inp=="yes":
           raise Exception("tried to recurse too deeply!")

如果我们将这些内联放在一个函数中,也许会更清楚。我们必须重命名变量,使它们不会相互覆盖。

def addtwo():
     numb0=input("enter any number")
     add0=int(numb0)+2
     print(add0)
     inp0 = input("do you wish to enter again")
     while inp0=="yes":
         numb1=input("enter any number")
         add1=int(numb1)+2
         print(add1)
         inp1 = input("do you wish to enter again")
         while inp1=="yes":
             numb2=input("enter any number")
             add2=int(numb2)+2
             print(add2)
             inp2 = input("do you wish to enter again")
             while inp2=="yes":
                 raise Exception("tried to recurse too deeply!")

您现在可以看到问题的直接原因:将inp2设置为“是”不会将inp1imp0设置为是。或者在原始代码中,在inp的嵌套调用中将addtwo设置为“是”不会将外部imp设置为是,因为每个函数都有自己的一组变量。

您现在还可以看到问题的根本原因:您不需要多个循环来执行此操作。递归(带有if)或while循环足以启用重复检查条件。通过兼顾两者,即使你解决了眼前的问题,你也会使事情变得不必要地复杂化。在这种情况下,while循环实际上是最简单的;将input语句放入其中并完全摆脱递归调用。