【问题标题】:Index error in Python: "string index out of range"Python中的索引错误:“字符串索引超出范围”
【发布时间】:2019-05-03 04:01:43
【问题描述】:

我是一名初级程序员,作为练习,我想编写一个代码,将句子中的每个单词打印到一个新行中,因为该单词以 h-z 开头。

这是我制作的代码:

random_phrase = "Wheresoever you go, go with all your heart"
word = ""
for ltr in random_phrase:
    if ltr.isalpha():
        word += ltr
    else:
        if word.lower()[0] > "g":
            print(word)
            word = ""
        else:
            word = ""

打印出来后,有一行空白,然后出现索引错误。我做错了什么?

【问题讨论】:

标签: python python-3.x


【解决方案1】:

尝试这样打印以 h-z 开头的句子的每个单词:

import string
# make the sentence lower case
random_phrase = "Wheresoever you go, go with all your heart".lower()
# split the sentence with space as separator into a list
words = random_phrase.split(" ")
start = "h"
end = "z"
# string.ascii_lowercase will give the lowercase letters ‘abcdefghijklmnopqrstuvwxyz’
letters = string.ascii_lowercase
# take the range h-z
allowed = letters[letters.index(start):letters.index(end)+1]
# iterate through each word and check if it starts with (h-z)
for word in words:
    if any(word.startswith(x) for x in allowed):
        print(word)

使用正则表达式:

import re
random_phrase = "Wheresoever you go, go with all your heart"
words = [s for s in random_phrase.split() if re.match('^[h-z,H-Z]', s)]
for word in words:
    print(word)

【讨论】:

  • 谢谢!效果很好。我正在尝试在没有导入关键字的情况下进行此练习,但这很棒。
【解决方案2】:
  • 在您的原始代码中,您有一个 , 导致您的代码中断,因为它不是字母数字字符,所以它进入 else 循环,您的 word 是一个空字符串,当您尝试获取第一个元素是空字符串时,您会得到IndexError。因此,最好检查像 if ltr != ' ': 这样的非空白字符。

  • 您可以在if条件之外重置word = ""

  • 您的代码不会检查字符串中的最后一个单词,您可以在 for 循环完成后进行检查

所以你重构的代码看起来像

random_phrase = "Wheresoever you go go with all your heart"
word = ""
for ltr in random_phrase:
    #Check for non-whitespace character
    if ltr != ' ':
        word += ltr
    else:
        #Check if word starts with g
        if word.lower()[0] > "g":
            print(word)
        #Reset word variable
        word = ""

#Check the last word
if word.lower()[0] > "g":
    print(word)

输出将是

Wheresoever
you
with
your
heart

您可以通过将字符串拆分为单词,使用string.split,遍历单词,然后检查每个单词的第一个字符是否位于h-z中,从而大大简化代码

random_phrase = "Wheresoever you go, go with all your heart"

#Split string into words
words = random_phrase.split()

#Iterate through every word
for word in words:

    #If the first character of the word lies between h-z, print it
    if word.lower()[0] > "g":
        print(word)

你的输出将是

Wheresoever
you
with
your
heart

【讨论】:

    【解决方案3】:

    我做错了什么?

    当您的进程在单词go 之后遇到逗号(非字母)时,它会确定go 不是以大于'g' 的字母开头,因此它将空字符串分配给word (@987654328 @)。下一项是非 alpha 空格,它尝试比较 word 的第一个字母,这是一个空字符串 (''[0] > 'g'),因此会导致 IndexError。

    您可以通过在比较之前检查word 是否为空字符串来修复它。
    改变

    if word.lower()[0] > "g":
    

    if word and word.lower()[0] > "g":
    

    An empty string evaluates to a boolean False:

    >>> s = ''
    >>> bool(s)
    False
    >>>
    

    andboolean operation;如果任一术语为 False,x and y 将评估为 False - 首先评估 x;如果是False,则返回它的值并且不会评估y。这被称为short circuit behavior.

    >>> x = ''
    >>> y = 'foo'
    >>> x and y
    ''
    >>> bool(x and y)
    False
    >>> if x and y:
    ...     print(True)
    ... else:
    ...     print(False)
    
    False
    >>> 
    

    我的条件语句的修复依赖于短路行为,因此如果word 是空字符串,则不会评估word[0]...。你的else 子句可以写得更明确一些——比如:

    ....
        else:
            if not word:
                pass
            elif word.lower()[0] > "g":
                print(word)
            word = ""
    

    但由于某种原因,我不喜欢它的外观。

    【讨论】:

    • 这太棒了!谢谢你。但是,如果我可能会问,如何简单地编写“word and”来检查它是否为空字符串?
    • 您可以通过将字符串拆分为单词并检查条件来大大简化您的代码! @JillandJill 如果对您有意义,请检查我的答案!
    【解决方案4】:

    我认为错误是因为这段代码:

        if word.lower()[0] > "g":
            print(word)
            word = ""
        else:
            word = ""
    

    您正在将 word 变量重置为空白。对空白进行索引不起作用(正如您尝试执行此代码时所看到的那样):

    word = ""
    word[0]
    
    IndexError: string index out of range
    

    【讨论】:

      【解决方案5】:

      总是寻求简单的解决方案...

      phrase = "Wheresoever you go, go with all your heart"
      for word in (phrase.lower()).split():
         first_letter = word[0]
         if first_letter > "g":
            print(word)
      

      【讨论】:

        猜你喜欢
        • 2015-01-19
        • 1970-01-01
        • 1970-01-01
        • 2012-02-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-10
        • 2019-12-24
        • 2013-09-25
        相关资源
        最近更新 更多