【问题标题】:why index out of range for 'in' line of code?为什么“in”行代码的索引超出范围?
【发布时间】:2021-04-17 20:05:44
【问题描述】:

我有下面的代码来删除任何输入字符串的元音:

def disemvowel(string_):
    
    vowels = ['a', 'e', 'i','o','u']
    
    for i in range(len(string_)): 
        if string_[i] in vowels: 
            string_ = string_.replace(string_[i],"")
    
    return string_

我似乎无法弄清楚为什么我在“if string_[i] in vowels:”行中收到“索引超出范围”错误;是不是因为 string_ 的长度和元音列表可能不匹配?

我对上面代码的理解是,我们将输入string_中的每个字符,并检查它是否与列表元音中的任何项目匹配,如果匹配则执行......还是我误解了使用“在”?

【问题讨论】:

  • 另外一个注释,string_.replace 将替换所有 string_[i] with '' 实例,所以当你这样做时,你实际上是在缩短你的字符串。但是您仍在迭代字符串的原始长度。最终,您最终检查了索引 10,但是您将字符串缩短到比这更短,并且您得到一个索引超出范围错误。这可能是index out of range 错误的来源。问题的解决方案已在下面添加。

标签: python if-statement


【解决方案1】:

这是因为您正在动态更改字符串,因此它的长度会发生变化。不如试试这个。

def disemvowel(string_):
    
    vowels = ['a', 'e', 'i', 'o', 'u']

    new_string = ''

    for i string_: 
        if i not in vowels: 
            new_string += i
    
    return new_string

【讨论】:

  • 顺便说一句,你不应该建立像new_string += i 这样的字符串,尽管它在这里可能不会有很大的不同
  • 由于您将元音替换为“”,这意味着字符串的长度每次减少 1,并且由于 for 循环遍历到字符串的旧长度,它会抛出一个错误,即 index is out范围。
【解决方案2】:

这是因为您在每次通过循环时都在更改 string_ 引用的字符串。所以字符串的实际长度是变化的,而迭代次数是由初始长度固定的。

例如。给定字符串"rata tat tat",当您将其作为range 调用的参数时,将具有len(string_) == 12。所以循环将迭代12 次。

第一关:

 string_ == "rata tat tat" and i == 0
 -> string_[i] == "r" 
 -> string_[i] not in vowels
 -> NO OP

第二遍:

 string_ == "rata tat tat" and i == 1
 -> string_[i] == "a" 
 -> string_[i] in vowels
 -> string_ == "rt tt tt"

第三遍:

 string_ == "rt tt tt" and i == 2
 -> string_[i] == " " 
 -> string_[i] not in vowels
 -> NO OP

第 4 到第 8 次迭代也不会执行任何操作,但在第 9 次迭代时,您的算法会:

第九关:

 string_ == "rt tt tt" and i == 8
 -> i == len(string_)
 -> string_[i] raises an IndexOutOfRange

您需要修改算法,使其改为在元音上运行,替换目标字符串中的每个。

【讨论】:

    【解决方案3】:

    解决方案:

    这只是你如何更换它们的问题,这里有一个快速修复:

    def disemvowel(string_):
        
        vowels = ['a', 'e', 'i','o','u']
        string_ = list(string_)
        for i in range(len(string_)): 
            if string_[i] in vowels: 
                string_[i] = ""
        
        return ''.join(string_)
    
    def disemvowel2(string_):
        vowels = ['a', 'e', 'i','o','u']
        return ''.join([letter for letter in string_ if letter not in vowels])
    
    s = "asdlkjsadkflja"
    print(disemvowel(s))
    print(disemvowel2(s))
    
    In: "asdlkjsadkflja"
    Out: "sdlkjsdkflj"
    

    注意第二个例子,通过使用列表推导,您可以简化您的 disemvowel 函数。

    关于每个步骤如何工作的说明:

    ''.join(['a','b','c','d']) 将列表中的字符连接在一起,在每个字符之间放置 '' -> 'abcd'

    list(string_)'abcd' 转换为['a','b','c','d']

    如果string_ 是一个列表,那么string_[i] = '' 将字符i 设置为一个空字符串。

    【讨论】:

      猜你喜欢
      • 2015-11-05
      • 1970-01-01
      • 1970-01-01
      • 2016-07-01
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      • 2020-09-04
      相关资源
      最近更新 更多