让字符串索引超出范围?蟒蛇3

时间:2017-09-21 18:21:29

标签: python-3.x uppercase lowercase

我的程序应该以字符串的形式输入并分成字符串,一个包含所有小写字母,下划线和点。另一个包括所有上壳,管道和空间。我不应该使用(用于功能)

def split_rec (letters):
    uppers = ""
    lowers = ""
    if letters[0].isupper() or letters[0] == "|" or letters[0].isspace():
        uppers += letters[0] + split_rec (letters[1:])
    elif letters[0].islower() or letters[0] == "_" or letters[0] == ".":
        lowers += letters[0] + split_rec (letters[1:])
    elif not letters:
        return lowers, uppers

你能告诉我更多关于我得到的错误吗?

  

如果字母[0] .isupper()或字母[0] ==“|”或字母[0] .isspace():   IndexError:字符串索引超出范围

2 个答案:

答案 0 :(得分:2)

您已定义递归函数split_rec调用split_rec (letters[1:])。由于字符串具有有限长度,因此最终您将将空字符串传递给它。这意味着你无法访问第一个字符,因为它没有第一个字符。

您可以使用警卫解决该问题:

def split_rec (letters):
    uppers = ""
    lowers = ""
    if not letters:
        return lowers, uppers
    if letters[0].isupper() or letters[0] == "|" or letters[0].isspace():
        uppers += letters[0] + split_rec (letters[1:])
    elif letters[0].islower() or letters[0] == "_" or letters[0] == ".":
        lowers += letters[0] + split_rec (letters[1:])
    elif not letters:
        return lowers, uppers

但这会无法解决问题:由于split_rec会返回两个字符串的元组,因此无法将其添加到字符中。您可以使用以下方法解决问题:

def split_rec (letters):
    if not letters:
        return lowers, uppers
    lowers, uppers = split_rec(letters[1:])
    if letters[0].isupper() or letters[0] == "|" or letters[0].isspace():
        uppers = letters[0] + uppers
    elif letters[0].islower() or letters[0] == "_" or letters[0] == ".":
        lowers = letters[0] + lowers
    return lowers, uppers

但是递归与扩展线性输入在Python中是一个坏主意:Python不优化递归调用,因此很容易得到 StackOverflow异常(这有与此网站无关。)

您最好使用生成器和join字符串:

def split_rec (letters):
    uppers = ''.join(c for c in letters if c.isupper() or c == "|" or c.isspace())
    lowers = ''.join(c for c in letters if c.islower() or c == "_" or c == ".")
    return lowers, uppers

答案 1 :(得分:1)

正如@willemVanOnsem指出的那样,你是在字符串上递减调用它而不是第一个字符。最后,您在空字符串上调用它,这就是您获得索引错误的原因。检查"字母"在做其他事情之前不是空的。

作为旁注,我不认为你的递归通话会按照你的预期进行。

你可以使用while循环吗?你提到不使用for循环?或者你必须使用递归?