为什么这个回文功能会失败?

时间:2017-03-14 14:02:32

标签: python

显然,最后应该是return is_palindrome(middle(word))代替最后两行。但为什么?该功能不应该在return True之后停止吗?

def first(word):
    return word[0]

def last(word):
    return word[-1]

def middle(word):
    return word[1:-1]

def is_palindrome(word):
    #base case
    if len(word) <= 1:
        return True
    if first(word) != last(word):
        return False
    else:
        is_palindrome(middle(word))

5 个答案:

答案 0 :(得分:2)

return True仅从调用它的函数的单个实例返回。由于这是一个递归函数,你最终会得到一堆函数实例,如下所示:

is_palindrome('abcdcba')
  is_palindrome('bcdcb')
    is_palindrome('cdc')
      is_palindrome('d')

递归最终在最后一个(字符串长度为1)中达到其基本情况并返回True。问题是,它只返回is_palindrome('cdc')实例。从那里开始,由于你没有告诉你的函数对结果做任何事情,它只返回None到下一个实例。同样,None会通过堆栈传播回初始函数调用。这不是非常有用。

    ^ None ^
is_palindrome('abcdcba')
      ^ None ^
  is_palindrome('bcdcb')
        ^ None ^
    is_palindrome('cdc')
          ^ True ^
      is_palindrome('d')

当你return递归调用的结果时,那会导致函数的每个实例接受 next 实例返回的内容,并传递它回到之前的实例,一直到原始调用。换句话说,它创建了一个链,允许最终结果一直传播回用户。

    ^ True ^
is_palindrome('abcdcba')
      ^ True ^
  is_palindrome('bcdcb')
        ^ True ^
    is_palindrome('cdc')
          ^ True ^
      is_palindrome('d')

答案 1 :(得分:1)

def first(word):
 return word[0]

def last(word):
 return word[-1]

def middle(word):
 return word[1:-1]

def is_palindrome(word):
 #base case
 if len(word) <= 1:
     return True
 if first(word) != last(word):
     return False
 else:
     return is_palindrome(middle(word))

print(is_palindrome("racecar"))

原因是,如果条件,你将从函数is_palindrome返回布尔值。因此,当您递归应用它时,您的基本情况将以true / false值退出。在else条件下进行递归调用时,需要返回该值。这就是递归树将如何在树的整个深度中保存所需的布尔值。

答案 2 :(得分:1)

对您的版本进行小幅调整,以便更好地了解正在发生的事情:

def first(word):
    return word[0]

def last(word):
    return word[-1]

def middle(word):
    return word[1:-1]

def is_palindrome(word):
    #base case
    if len(word) <= 1:
        print(1)
        return True
    if first(word) != last(word):
        print(2)
        return False
    else:
        print(3)
        is_palindrome(middle(word))

现在正在运行is_palindrome('abcba')将打印

3
3
1

正如我认为您对递归方法的预期,除了输出结尾没有True。您会看到,首先您调用了is_palindrome('abcba'),然后是is_palindrome('bcb'),然后是is_palindrome('c')。这些调用中的最后一个将True返回到第二个,第二个将None返回到第一个,第一个最终返回None,如您所见is_palindrome('abcba') is None }。这就是前面提到的最后一行前面的return语句的原因:原始调用将返回的内容很重要,所以即使在某个时刻达到return True,这也不是输出你的代码。

我希望这会有所帮助。

PS:检查字符串是否是回文更容易:只需检查是否word == word[::-1]

答案 3 :(得分:0)

def first(word):
    return word[0]

def last(word):
    return word[-1]

def middle(word):
    return word[1:-1]

def is_palindrome(word):
    #base case
    if len(word) <= 1:
        return True
    elif first(word) != last(word):
        return False
    else:
        return is_palindrome(middle(word))

这里的代码就像递归一样,函数is_palindrome返回true或false,但你没有使用它.Ex

is_palindrome('ana')
 is_palindrome('n')
  return True
 return True
return True

答案 4 :(得分:0)

Rawing已经通过添加&#39; return&#39;修复了您的问题。 关于你仍然不了解它的工作原理&#39;评论:它是一个递归函数。起初,递归可能很难理解。如果你认为这不是一个调用,而是整个堆栈,只有最后一个返回true或false,这可能会有所帮助。 此外,您可以省略其他:&#39;。