【问题标题】:Recursive sum function in python?python中的递归求和函数?
【发布时间】:2016-06-03 01:03:19
【问题描述】:

基本上我正在尝试创建一个函数 r_sum(n),它将返回前“n”个倒数的总和:例如sum(5) = 1 + 1/2 + 1/3 + 1/4 + 1/5 。我是递归的新手,在实现时遇到了麻烦。这是我到目前为止的代码:

def r_sum(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return 1/n

我想我已经创建了函数的基础,但我不确定我会在哪里调用函数本身。到目前为止,我意识到该函数只会返回 1/n 的值。我怎样才能添加到这个,以便我有函数调用本身来计算这个总和?

【问题讨论】:

  • def sum_to(n): return 0 if n == 0 else 1./n + sum_to(n-1) — »太容易了。也许你没有我想象的那么坚强。«
  • stackoverflow.com/questions/36163040/… 这是课程的一部分吗?
  • 嗯,应该保留一条注释,指出 在 Python 3 中,即使 n 是一个整数,像 1/n 这样的东西也会创建一个浮点数。由于这对于其他编程语言来说并不常见(即使是 Python 2 也会返回一个 int,对于大多数 n 来说是 0),因此该注释仍然有意义。
  • 你在哪里学习递归?当然它应该有例子来说明一个函数是如何调用自己的。
  • 我意识到这是一个简单的解决方法,如果问题是多余的,我们深表歉意。此外,这不是课程的一部分。

标签: python python-3.x recursion


【解决方案1】:

想一想:

sum(5) = 1 + 1/2 + 1/3 + 1/4 + 1/5

作为:

sum(5) = 1/5 + sum(4)
sum(4) = 1/4 + sum(3)
sum(3) = 1/3 + sum(2)
sum(2) = 1/2 + sum(1)
sum(1) = 1

这样:

sum(x) = 1/x + sum(x-1)
sum(1) = 1

因此最后一种情况应该是:

return 1/n + sum_to(n - 1)

【讨论】:

    【解决方案2】:

    试着考虑解决问题的一部分,以便其余部分是同一问题的另一个实例,只是针对较小的部分。

    def sum_to(n):
        if n == 0:
            return 0.0
        elif n == 1:
            return 1.0
        else:
            return 1.0/n + sum_to(n-1)
    

    【讨论】:

      【解决方案3】:

      这些数字更广为人知的是Harmonic Numbers。值得注意的是,通常不定义 H0,但这不是重点。

      你想要sum_to(n)返回什么?你可能期待1/n + 1/(n-1) + ... 对吧?所以我们不应该简单地返回1/n。您应该查看该表达式的其余部分并找到可以找到 sum_to(n - 1) 的位置。

      【讨论】:

        【解决方案4】:

        编写递归函数时,需要做两件事:

        • 停止案例
        • 另一种一般情况(递归定义)

        在这里,您的停止条件为 0。我们知道 sum_to(0) == 0
        一般情况为:sum_to(n) == 1.0/n + sum_to(n - 1)

        剩下要做的就是将这些加入一个函数中:

        def sum_to(n):
            if n == 0:
                return 0
        
            return 1.0/n + sum_to(n - 1)
        

        【讨论】:

          【解决方案5】:

          使用生成器是解决这个问题的 Pythonic(与迂腐相对)的方式。

          def g_sum(n):
              """
              Solution using generators instead of recursion.
              Input validation suppressed for clarity.
              """
              return sum(1/x for x in range(1, n+1))
          
          def r_sum(n):
              """
              Recursive solution proposed by @Alfe
              """
              return 0 if n == 0 else 1/n + r_sum(n-1)
          

          对函数计时表明生成器的解约为。两倍快:

          • 发电机:
            • %timeit -n 10000 v1 = g_sum(100)
            • 10000 loops, best of 3: 9.94 µs per loop
          • 递归:
            • %timeit -n 10000 v2 = r_sum(100)
            • 10000 loops, best of 3: 22 µs per loop

          此外,递归实现将很快达到递归限制,使其在实际使用中非常不切实际。

          具体来说:r_sum(1000) 失败并显示RecursionError: maximum recursion depth exceeded in comparison

          【讨论】:

            【解决方案6】:

            你可以通过两种方式做到这一点

            def r_sum(n):
                if n == 1:
                    return 1
                return (1/n) + r_sum(n-1)
            

            def r_sum(n):
                return sum(map(lambda x:1.0/x, xrange(1, n+1)))
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2017-01-20
              • 1970-01-01
              • 2011-03-07
              • 2021-03-16
              • 2012-11-22
              • 2020-04-16
              • 2019-10-18
              相关资源
              最近更新 更多