这个Python函数不应该一直返回6吗?

时间:2012-12-04 00:57:38

标签: python

我是Python新手并学习功能。我遇到了以下功能,并在我的智慧结束时了解它是如何工作的。在我看来,无论b的价值如何,答案应该总是六个,但事实并非如此。

CODE

def mult(a, b):
    if b == 0:
        return 0
    rest = mult(a, b - 1)
    value = a + rest
    return value
print "3 * 2 = ", mult(3, 2)

我对发生的事情的理解

  1. 由于b不为0,因此
  2. rest被赋予值3, 1并且它再次运行该功能
  3. 由于b为1并且等于0,因此会进入rest
  4. rest被赋予值3, 0并且它再次运行该功能
  5. 由于b现在为零,因此返回值0
  6. 然后转到value,其值为3 + 3,a的值为3,rest的值为3,即(3,0)
  7. 返回值6
  8. 如果我指定mult(3,4),则返回值12.根据我的理解,这是不可能的。显然,我不了解逻辑流程。我做错了什么?

5 个答案:

答案 0 :(得分:4)

此功能的基本逻辑是:

我们(a添加1并从b减去b == 0)直到def mult(a, b): value = 0 while b > 0: b = b - 1 value = value + a return value 。你可能会更喜欢这样:

mult

只有代替while循环,你的函数才会自动调用。我设法自己联系(a, b),他愿意解释:

  

嗨,我的名字很多,我是一个递归者。递归是一种常见的品种   在Computer Sciencia,我们有一个特殊的功能;我们可以克隆   我们自己。可悲的是,我因无法成倍而受到诅咒。不过,我   我想把自己的梦想当作一个乘数,我确实找到了办法   去做吧。方法如下:

     

当你让我乘以(a, b - 1)时,我会产生一个克隆   并问他a。克隆重复此过程直到   生成一个被问到的克隆(0b)。当发生这种情况时   (当时有一行我自己+ 0克隆),他回答了   产生他的克隆:a。该克隆反过来将0 + a添加到他的内容中   刚刚被告知(第一次是a)并回答这个问题   克隆在他面前。这个过程一直重复,直到我得到答案   通过克隆我自己产生了。我添加def mult(a, b): # Should I ask a clone? if b == 0: # No! I reply 0 to my asker. return 0 # Yes! I spawn a clone and ask him (a, b - 1) and wait for an answer to # store in 'rest' rest = mult(a, b - 1) # I take the answer and add to it the 'a' I was told value = a + rest # I return the value I calculated to my asker return value print "3 * 2 = ", mult(3, 2) # Here someone asks me (3, 2) 并将其作为最终结果返回   回答你!

{{1}}

答案 1 :(得分:3)

您可以检测代码,以便更轻松地查看正在发生的事情

def mult(a, b):
    print "mult(%s, %s)"%(a, b)
    if b == 0:
        return 0
    rest = mult(a, b - 1)
    value = a + rest
    print "returns %s"%value
    return value
print "3 * 2 = ", mult(3, 4)

3 * 2 =  mult(3, 4)
mult(3, 3)
mult(3, 2)
mult(3, 1)
mult(3, 0)
returns 3
returns 6
returns 9
returns 12
12

由于递归,print语句是嵌套的

即。 mult(3, 0)返回3,mult(3, 1)返回6,依此类推

答案 2 :(得分:2)

    使用mult()调用
  1. 3, 2(这是#1)

  2. 使用mult()调用3, 1(这是第2次调用)

  3. 使用mult()调用3, 0(这是第3次调用)

  4. 返回0(因为b为零)来调用#2

  5. 呼叫#2现在返回3 + 0,呼叫#1

  6. 呼叫#3现在返回3 + 3

  7. 基本上,每次调用都会将a值增加a,递归地深入研究istelf b次。因此,将4次加入自身4次将产生12次。

答案 3 :(得分:2)

你的逻辑是正确的直到子弹5.然后在6你跳过一些步骤。 这是一个递归函数。通过在纸上绘制事件树更容易理解它,但让我们首先恢复你的逻辑:

多重峰(3,4):

 1. a = 3, b = 4
 1. rest = mult(3, 3)
 2. a = 3, b = 3
 2. rest = mult(3, 2)
 3. a = 3, b = 2
 3. rest = mult(3, 1)
 4. a = 3, b = 1
 4. rest = mult(3, 0)
 5. a = 3, b = 0
 5. return 0
 4. value = 3 + 0
 4. return 3
 3. value = 3 + 3
 3. return 6
 2. value = 3 + 6
 2. return 9
 1. value = 3 + 9
 1. return 12

在上面的示例中,行开头的每个数字代表递归中的步骤。它从步骤1开始,直到这种情况下的步骤5,然后再返回1,直到第1步再次给出你的最终答案。

该函数通过求和实现乘法的概念。例如,3 * 4与将数字'4'相加三次相同。

答案 4 :(得分:1)

这是一种直观地了解递归如何工作的方法:

COUNTER = 0

def mult(a, b):
    global COUNTER

    COUNTER+=1
    print " "*COUNTER + "Called with", a,b

    if b == 0:
        return 0
    rest = mult(a, b - 1)
    value = a + rest

    COUNTER -= 1
    print " "*COUNTER, "Value:", value 

    return value

print "3 * 4 = "
print mult(3, 4)

输出

3 * 4 = 
 Called with 3 4
  Called with 3 3
   Called with 3 2
    Called with 3 1
     Called with 3 0
     Value: 3
    Value: 6
   Value: 9
  Value: 12
12

您可以看到调用堆栈如何一直向下(b == 0),然后将值返回到链的顶部。