【问题标题】:Why does my recursive function with if-elif statements return None?为什么我的带有 if-elif 语句的递归函数返回 None?
【发布时间】:2010-09-15 16:46:49
【问题描述】:

我目前正忙于学习 Python,但在递归函数方面遇到了一些障碍。在Think Python 中,其中一个练习是编写一个函数,使用以下定义确定数字 a 是否是数字 b 的幂:

"一个数a是b的幂,如果它可以被b整除,a/b是b的幂。编写一个名为is_power的函数,接受参数a和b,如果a是a的幂则返回True b.”

我的函数的当前状态是:

def isPower(a,b):
    return a % b == 0 and (a/b) % b == 0

print isPower(num1,num2)

事实上,这会产生我期望的结果。然而,本章的重点是编写递归函数以减少冗余,我不太确定如何将最终的 "(a/b) % b == 0" 转换为递归。我尝试过:

def isPower(a,b):
    if a % b != 0:
        return False
    elif isPower((a/b),b):
        return True

但这只是返回无。

递归这个函数的正确方法是什么?

【问题讨论】:

  • 您应该注意,'/' 运算符的含义在 Python 3+ 中发生了变化,从返回整数变为返回浮点数,因此您的代码会中断。将其更改为 '//' ,这将始终返回一个 int。
  • 请注意,您的第一次尝试不会检查 a 是否是 b 的幂,它会检查 a 是否是 b^2 的倍数。试试 isPower(12,2),它会返回 True。
  • 据说,你的第一个版本的 isPower 坏了——它只会显示a 是否是b^2 的倍数。例如,对于isPower(2, 1),它将返回 true,这绝不应该是 true。就此而言,您可能希望确保任何递归版本在继续之前检查 (b==1 && a!=1),否则它将陷入无限循环或返回错误的内容。

标签: python recursion


【解决方案1】:

当 a == 1 时,您忘记了基本情况:

def isPower(a,b):
    if a == 1:
        return True
    if a % b != 0:
        return False
    elif isPower((a/b),b):
        return True
    else
        return False

但是,这还有一些其他问题 - 如果 a 为 0,那么它永远不会完成,如果 b 为 0,那么你将得到一个被零除。

这是一个详细的解决方案,据我所知,它适用于所有整数组合:

def isPower(a,b):
    if a == 0 or b == 0:
        return False
    def realIsPower(a, b):
        if a == 1:
            return True
        elif a%b != 0:
            return False
        elif realIsPower((a/b), b):
            return True
        else:
            return False
    return realIsPower(a, b)

编辑:我的代码不适用于 a 和 b 均为负数的情况。我现在正在比较它们的绝对值。

EDIT2:愚蠢的我,x^0 == 1,所以 a == 1 应该总是返回 true。这也意味着我不必在递归之前将 a 与 b 进行比较。谢谢@Javier。

【讨论】:

  • 谢谢。这准确地澄清了我所缺少的。在早些时候对它进行了一些修改之后,我已经达到了最大递归循环,但无法弄清楚如何停止它。我想我假设解释器会知道我只是希望它在再次执行后停止。现在我明白了,在编写递归调用时,甚至允许到达该 ELIF 分支的测试之一必须能够停止它。这只是一个练习功能,因此允许以 1 为底就可以了,但感谢您全力以赴的帮助!
  • 嘿,很高兴我能帮上忙!永远记住,所有递归函数都需要两件事——基本情况和递归调用。有时(例如在这种情况下)有多个基本情况。
【解决方案2】:

你需要一个额外的情况,当两个条件都返回 false 时

def isPower(a,b):
    if a % b != 0:
        return False
    elif isPower((a/b),b):
        return True
    else
        return False

【讨论】:

  • 我认为你的意思是 a % b,而不是 a & b
  • 这将始终返回 false。
  • 实际上,您也需要考虑基本情况。我刚刚编辑掉了错字。
  • 这仍然对我不起作用,在某些时候该函数应该在非递归条件下返回 True。
  • 是的,在回家并对其进行一些测试后,它始终返回 False。回到绘图板!
【解决方案3】:
def isPower (a,b):
    return a==1 or (a!=0 and b!=0 and b!=1 and isPower((a/b),b))

【讨论】:

  • 如果 a 最初为 1,这将始终返回 true,但仅当 b 为 1 或 -1 时才会如此。
  • 感谢您的帮助,哈维尔。你和 Niki 的答案结合起来正是我需要的,我的脑海中的一切都在点击。我理解脚手架和编写过于冗长的代码的重要性,并在此过程中进行大量测试,但是一旦我对语法和逻辑感到满意,我希望能够生成产生相同效果的最短代码。这个答案很高兴看到 Niki 的答案看起来像一个单线以供将来参考。太糟糕了,我不能有两个被接受的答案!
  • @Niki Yoshiuchi:1 是任意数的幂(x^0 = 1 表示任意 x)
【解决方案4】:

这是我的代码。根据我的测试,它有效:

def ispower(a, b):

    if b == 1 or b == 0:
        return False
    if b <= 0 or a <= 0:
        return False
    if a % b == 0:
        if ((a / b) / b) == 1:
            return True
        else:
            return ispower(a / b, b)
    else:
        return False
        print ispower(-10, 2)

【讨论】:

    【解决方案5】:

    试试这个,

    def ispower(a,b):
      if b==a:
        return True
      elif a<b:
        return False
      else:
        return ispower(a*1.0/b, b)
    

    【讨论】:

    • 一个解释将有助于这个答案
    【解决方案6】:
    def is_power (a, b):
    
        if a == 1:
            return True
        if a == 0 and b == 0:
            return True
        if a == 0 or b == 0:
            return False
        if a%b != 0:
            return False
        elif is_power ((a/b), b):
            return True
    

    【讨论】:

      【解决方案7】:

      这是我的答案,它更干净一点:

      def is_power(a, b):
          if a == 1:
              return True
          if a == 0 or b == 0:
              return False
          if a % b == 0 and is_power(a/b, b):
              return True
          else:
              return False
      

      【讨论】:

        猜你喜欢
        • 2021-11-13
        相关资源
        最近更新 更多