【问题标题】:How to reduce parameters needed in recursive function definition (for calculation of a*b)如何减少递归函数定义中所需的参数(用于计算a*b)
【发布时间】:2018-01-17 22:22:59
【问题描述】:

我有一个计算a*b 的递归函数,但是当我调用它时,我不想给它一个值:recursive_sum(5,5,0) 其中0 是保存的总和。

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),而不必担心将0 传递给saved

【问题讨论】:

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

标签: python recursion parameters arguments


【解决方案1】:

整个方法只对整数有效,但这可能会让你直截了当:

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

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

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

尝试实现递归阶乘函数。这可能是最容易编写的(除了求和)递归函数。

【讨论】:

    【解决方案2】:

    您的代码有两个问题。

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

    其次,您不是 returning 递归调用的结果(而是将结果乘以 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 中的非尾递归代码可能比此版本更好。

    【讨论】:

    • 函数return是什么意思?为什么和叫它不一样?
    • @Arkan return 是您指定函数调用产生的值的方式。
    【解决方案3】:
    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-21
      • 2018-06-20
      • 2020-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多