如何减少递归函数定义中所需的参数(用于计算a * b)

问题描述:

我有一个递归函数,可以计算出a*b,但是当我称之为我不想给它一个值时:recursive_sum(5,5,0)其中0是已保存的总和。如何减少递归函数定义中所需的参数(用于计算a * b)

def recursive_sum(a,b,saved): 
    if b == 1: 
     saved+=a 
     return saved 
    saved += a 
    b -= 1 
    b*recursive_sum(a,b,saved) 

我明白这是一个很简单的例子

当我添加行save=0,所以我不必须通过争论毫无意义,显然,该值重置为0在每次迭代。

我的问题:有没有执行我的函数调用recursive_sum(2,2)工作,而不必担心传递0saved的方法吗?

+2

你可以使用类似'def recursive_sum(a,b,saved = 0):' – PRMoureu

您的代码有两个问题。

首先,你没有在你的函数声明中包含缺省值saved(尽管你提到了尝试)。我怀疑当你尝试它时,你实际上做了一些不同的事情(在递归调用中传递关键字参数)。

其次,您不是return递归调用的结果(相反,您将结果乘以b,这没有任何意义,也没有任何用处,因为您放弃了结果) 。

这里有一个固定的版本:

def recursive_sum(a,b,saved=0): # provide default value for saved here 
    saved+=a # minor improvement: moved this line here rather than repeating it twice below 
    if b == 1: 
     return saved 
    b -= 1 
    return recursive_sum(a,b,saved) # return result of recursive call (and don't multiply) 

我怀疑,当你尝试过使用默认值,你也(或代替)把saved=0在递归调用的函数结束时(不仅在def线)。这将无法正常工作,因为它将0作为关键字参数传递,忽略您已拥有的值saved

这个版本的代码是“尾递归”,因为你的return递归调用的结果没有做任何事情。这种递归在一些其他编程语言中具有一些性能优势,但是可惜的是,不是Python。除非由于某些特定原因(例如,您需要将其用于作业分配)选择尾递归,否则RagingRoosevelt's answer中的非尾递归码可能比此版本更好。

+0

''return'函数是什么意思?为什么调用它不同? – Arkan

+1

@Arkan'return'是你如何指定函数调用产生的值。 – RagingRoosevelt

这整个的做法才真正适用于整数,但是这可能直接设置你:

def recursive_sum(a,b): 
    if b == 1: 
     return a 
    return a + recursive_sum(a, b-1) 

这里的想法是,你return语句需要调用函数调用的下一个迭代,然后使用结果它收到计算它自己的返回值。当你写一个递归函数时,你真的在​​写f(f(... f(x)))。你需要实现两个组件:

  1. 一般(递归)的情况 - 你如何使用先前的结果来计算下一个结果的顺序?
  2. 基本情况 - 你如何确定你不需要任何额外的递归?在这种情况下,您只需返回一个值而不必再次调用该函数。

尝试实施递归阶乘函数。这也许是最简单的(除了一个总和)递归函数。

def recursive_sum(a,b): 
    def iterative_sum(x, saved): 
     if x == 0: 
      return saved 
     else: 
      return iterative_sum(x-1, saved+a) 
    return iterative_sum(b,0)