【问题标题】:IndexError: string index out of range for reading first line in a file pythonIndexError:字符串索引超出范围,用于读取文件python中的第一行
【发布时间】:2015-01-18 02:50:20
【问题描述】:

您好,我正在编写打开文件的代码。如果文件中当前正在读取的行包含标记任务的内容,它会读取文件并执行特定任务。

我要做的第一件事是读取第一行并将其添加到运行分数中,然后继续处理该文件。但是,我遇到了错误:indexError: string index out of range.

我只是不明白,我觉得这不应该发生。

这里是错误引用的代码。其次是实际错误。然后是上下文的完整代码。

    def processScores( file, score):
#opens file using with method, reads each line with a for loop. If content in line
#agrees with parameters in  if statements, executes code in if statment. Otherwise, ignores line    

    with open(file,'r') as f:
        for line in f:  #starts for loop for all if statements
            line = line.strip()
            if line[0].isdigit():
                start = int(line.strip())
                score.initialScore(start) #checks if first line is a number if it is adds it to intial score

错误

   processScores('theText.txt',score)
Grabing intial score from file, inital score set to 50
Traceback (most recent call last):
  File "<pyshell#28>", line 1, in <module>
    processScores('theText.txt',score)
  File "C:/Users/christopher/Desktop/hw2.py", line 49, in processScores
    if line[0].isdigit():
IndexError: string index out of range

总代码

    class Score:
# class to hold a running score, from object to parameter
# also to set number of scores that contribute to total of 1

    def __init__(self):
#initalizes the running score and score input accumilators
        self.runScore = 0
        self.scoreInputs = 0

    def initialScore(self, start):
#takes the initial score in line one of the file and updates
#the running score to the inital score
        self.runScore += start
        print('Grabing intial score from file, inital score set to ' + str(start))


    def updateOne (self, amount):
#updates running score by amount and Score input by 1
        self.runScore += amount
        self.scoreInputs += 1
        print('Adding ' + str(amount) + ' to score, number of scores increased by 1. Current number of points scored ' + str(self.runScore) + ',  current number of scores at ' + str(self.scoreInputs))

    def updateMany(self,lst):
#updates running score by the sum of the list and score inputs by the amount of
# number of items in the list
        self.runScore += sum(lst)
        self.scoreInputs += len(lst)
        print('Adding the sum of ' + str(len(lst)) + 'scores to score. Score increased by ' +  str(sum(lst)) + '. current number of points scored ' + str(self.runScore) + ', current number of scores at ' + str(self.scoreInputs)) 

    def get(self):
#returns the current score based on total amount scored
        print('Grabbing current score')
        print(self.runScore)

    def average(self):
#returns the average of the scores that have contributed to the total socre
        print('calculating average score')
        print(self.runScore // self.scoreInputs)

score = Score() # initize connection       

def processScores( file, score):
#opens file using with method, reads each line with a for loop. If content in line
#agrees with parameters in  if statements, executes code in if statment. Otherwise, ignores line    

    with open(file,'r') as f:
        for line in f:  #starts for loop for all if statements
            line = line.strip()
            if line[0].isdigit():
                start = int(line.strip())
                score.initialScore(start) #checks if first line is a number if it is adds it to intial score

            elif line == 'o' or line == 'O':
                amount = int(next(f))
                score.updateOne(amount) #if line contains single score marker, Takes content in next line and
                                        #inserts it into updateOne
            elif line == 'm'or line == 'M':
                scoreList = next(f)
                lst = []
                for item in scoreList: 
                    lst.append(item)
                    score.updateMany(lst) # if line contains list score marker, creates scoreList variable and places the next line into  that variable
                                          #  creates lst variable and sets it to an empty list
                                          # goes through the next line with the for loop and appends each item in the next line to the empty list
                                          # then inserts newly populated lst into updateMany

            elif line == 'X':
                score.get(self)
                score.average(self) # if line contains terminator marker. prints total score and the average of the scores.
                                    # because the file was opened with the 'with' method. the file closes after 

文件的样子

50

30

40

M

10 20 30

o

5

1 2 3

X

通过代码我可以看到文件正在读取第一行,您可以在代码失败之前通过 print 语句看到。

processScores('theText.txt',score)

从文件中获取初始分数,初始分数设置为 50

该打印语句正在这行代码上运行

def initialScore(self, start):
#takes the initial score in line one of the file and updates
#the running score to the inital score
        self.runScore += start
        print('Grabing intial score from file, inital score set to ' +  str(start))

所以我假设它正在进入代码的下一部分。但我不确定。

非常感谢大家

【问题讨论】:

  • 您要处理的文件是什么?
  • 嗨@Th3Cuber 我已经编辑了我的问题,以便为您提供有关文件和代码的更好信息,非常感谢您对此进行调查。总代码后的编辑接近底部

标签: python file indexing


【解决方案1】:

看起来line[0] 不存在,即行是空的,所以您无法读取它的第一个字符。您的文件很可能是空的,或者文件末尾有一个空行。要调试,您可以通过执行print lineprint len(line) 之类的操作来检查每一行。您可能还想在代码中添加一些检查,以确保您不会尝试处理空行,例如 if line:if line.strip():,如果后面的行中剩余字符,则计算结果为 True行首和行尾的空白已被删除。

编辑:在你的情况下,你想要这样的东西:

with open(file,'r') as f:
    for line in f:
        # strip white space
        line = line.strip()
        # if line is not empty
        if line:
            if line[0].isdigit():
                # do this
            elif line == 'o'
                # do that
            # etc...

【讨论】:

  • 嗨@figs 我已经编辑了我的问题,以便为您提供有关文件和代码的更好信息,非常感谢您对此进行调查。总代码后的编辑接近底部
  • 是的,如果每隔一行是空的,那么这将解释你的错误。
  • 天哪!我什至没有考虑到这一点......跛脚......所以现在我必须做出一个 elif 声明来说明一个空白行哈哈。这当然糟透了,它就在我脸上,我没有看
  • 您的空行不需要elif,只需忽略它们即可。我用一个例子更新了我的答案......
  • 谢谢@figs 是的,我正在考虑我将如何做到这一点。感谢您的意见
【解决方案2】:

您的行在 strip() 之后包含空字符串作为@figs 的建议,只需更改为:

...
if line and line[0].isdigit():
    start = int(line)

而且您不需要重复 strip() 两次。

【讨论】:

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