【问题标题】:Am getting IndexError: string index out of range -Python我得到IndexError:字符串索引超出范围-Python
【发布时间】:2021-03-10 15:17:23
【问题描述】:
def is_palindrome(x, pos_index, neg_index):
    if x[pos_index] == x[neg_index]:
        print("")
    else:
        return False

    pos_index += 1
    neg_index -= 1

    is_palindrome(x, pos_index, neg_index)


print(is_palindrome("racecar", 0, -1))

【问题讨论】:

  • 欢迎来到 StackOverflow。请更详细地解释什么不起作用。仅仅粘贴代码是不够的。也看看how to ask a good question
  • 对不起 Dominik 这是我的第一个问题,当我在 pycharm 中运行特定代码时出现索引超出范围错误?

标签: python recursion indexing palindrome


【解决方案1】:

您的结束条件缺失。您每次都调用该函数,因此您的 pos_index 变为 6 ('r')。之后您应该停止,而是添加一个并重新启动该功能。所以你得到了一个超出范围的字符串索引。

还有一点注意,对于您的下一个问题,一些补充信息或特定问题会很好。

【讨论】:

    【解决方案2】:

    如果我要修复您的代码并保留大部分代码,我会执行以下操作:

    def is_palindrome_recursive(x, pos_index, neg_index):
        if -neg_index >= len(x):
            return True
    
        if x[pos_index] != x[neg_index]:
            return False
    
        pos_index += 1
        neg_index -= 1
    
        return is_palindrome_recursive(x, pos_index, neg_index)
    
    def is_palindrome(string):
        return is_palindrome_recursive(string, 0, -1)
    
    print(is_palindrome("racecar"))
    

    主要变化是:一个额外的return 案例,我们递归地将输入减少到一个字母或更少;处理我们递归调用的结果——一个常见的递归初学者错误。

    由于这不是一个固有的数学问题,我倾向于将数字和数学运算符排除在解决方案之外。我还将参数视为一个序列,而不是一个字符串,以允许在 strlist 字符之间进行流畅的转换:

    def is_palindrome(sequence):
        if sequence:
            first, *rest = sequence
    
            if rest:
                *middle, last = rest
    
                if first != last:
                    return False
    
                return is_palindrome(middle)
    
        return True
    
    if __name__ == "__main__":
        print(is_palindrome("racecar"))
        print(is_palindrome("radar"))
        print(is_palindrome("ABBA"))
        print(is_palindrome("pop"))
        print(is_palindrome("cc"))
        print(is_palindrome("I"))
        print(is_palindrome(""))
    

    我希望这个问题的递归谓词函数有三个return 可能性:return True 成功; return False 失败; return is_palindrome(...) 一个我还不知道的递归。

    【讨论】:

      【解决方案3】:

      您收到错误的原因是因为is_palindrome() 连续调用is_palindrome() 并且如果单词 是回文则没有停止。仅当单词 不是 回文时,该函数才会返回。由于没有停止点,最终正负索引都会超过字符串的最大索引。我会尝试使用这个:

      def is_palindrome(phrase):
          phrase = "".join(phrase.lower().split())
          index, imax = 0, len(phrase)-1
          while index < imax-index:
              if phrase[index] != phrase[imax-index]:
                  return False
              index += 1
          return True
      

      请注意,这只检查直到index 尽可能接近字符串的中间(可以通过将print(index) 放入while 循环中来观察)。这样,代码就不会“仔细检查”字符串的后半部分。

      以下是一些测试运行:

      >>> is_palindrome("racecar")
      True
      >>> is_palindrome("bus")
      False
      >>> is_palindrome("a man a plan a canal panama")
      True
      >>> is_palindrome("AABBAA")
      True
      

      但是,如果您想保留递归性质,可以尝试使用以下方法:

      def is_palindrome(phrase, positive=0, negative=-1):
          phrase = ''.join(phrase.lower().split())
          if positive >= len(phrase):
              return True
          if phrase[positive] == phrase[negative]:
              return is_palindrome(phrase, positive+1, negative-1)
          return False
      

      一些测试运行:

      >>> is_palindrome("racecar")
      True
      >>> is_palindrome("bus")
      False
      >>> is_palindrome("A man a plan a canal panama")
      True
      >>> is_palindrome("AABBAA")
      True
      

      【讨论】:

      • OP 的解决方案本质上是递归的,他们标记了 [recursion] 但您的解决方案似乎没有递归。
      【解决方案4】:

      试试这个:

      def is_palindrome(x, pos_index, neg_index):
          if x[pos_index] == x[neg_index]:
               print("")
          else:
              return False
          if pos_index==len(x)-1:
              exit()
          else:
               pos_index += 1
               neg_index -= 1
          
          is_palindrome(x, pos_index, neg_index)
           
      
      
      print(is_palindrome("racecar", 0, -1)) 
      

      【讨论】:

      • 从名称is_* 来看,我希望有一个谓词函数,即返回TrueFalse 的函数。这个函数做了件事情之一,它可能会返回False,它可能会返回None,或者它可能会把你踢出Python!
      【解决方案5】:

      递归是一种函数式遗产,因此将其与函数式风格一起使用会产生最佳效果。这意味着避免诸如突变、变量重新分配和其他副作用之类的事情 -

      1. 如果输入字符串 s 少于 2 个字符,我们总是有回文。返回真。
      2. (归纳)s 是 2 个字符或更多。如果第一个字符与最后一个字符不匹配,则返回 false
      3. (归纳)s 为 2 个或更多字符,并且第一个字符与最后一个字符匹配。返回子问题的结果,s[1:-1]
      def is_palindrome(s):
        if len(s) < 2:
          return True                    #1
        elif s[0] != s[-1]:
          return False                   #2
        else:
          return is_palindrome(s[1:-1])  #3
      
      is_palindrome("racecar")
      is_palindrome("aceca")
      is_palindrome("cec")
      is_palindrome("e")
      True
      

      我们可以把底部的两个逻辑分支合二为一——

      def is_palindrome(s):
        if len(s) < 2:
          return True
        else:
          return s[0] == s[-1] and is_palindrome(s[1:-1])
      

      最后我们可以完全折叠if 并简单地对整个表达式使用逻辑运算符 -

      def is_palindrome(s):
        return len(s) < 2 or s[0] == s[-1] and is_palindrome(s[1:-1])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-30
        • 1970-01-01
        • 1970-01-01
        • 2017-03-26
        • 2012-02-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多