为什么在读取.txt文件中的部分行时抛出ValueError with int()内置?

2024-10-02 22:23:03 发布

您现在位置:Python中文网/ 问答频道 /正文

这是从studentNamesfile.txt读取的子例程

def calculate_average():
'''Calculates and displays average mark.'''
test_results_file = open('studentNamesfile.txt', 'r')

total = 0
num_recs = 0
line = ' '
while line != '':
    line = test_results_file.readline()
    # Convert everything after the delimiting pipe character to an integer, and add it to total.
    total += int(line[line.find('|') + 1:])
    num_recs += 1
test_results_file.close()

[num_recs保存从文件中读取的记录数。]

studentNamesfile.txt的格式如下:

Student 01|10
Student 02|20
Student 03|30

等等。此子例程用于读取文件中所有学生记录的标记,但在运行时出现以下错误:

Traceback (most recent call last):
  File "python", line 65, in <module>
  File "python", line 42, in calculate_average
ValueError: invalid literal for int() with base 10: ''

这个错误很明显,但我不明白为什么会抛出它。我尝试跟踪line[line.find('|') + 1:]的值,但是Python坚持认为在前一行中使用print(line[line.find('|') + 1:]时它具有正确的值(例如10)。怎么了

更新:我正在考虑line[line.find('|') + 1:]包含换行符的可能性,它正在中断int()。但是使用line[line.find('|') + 1:line.find('\\')]并不能解决这个问题,同样的错误也会被抛出


Tags: testtxt错误linefind例程studentresults
3条回答

此处:

while line != '':
    line = test_results_file.readline()

当您到达文件的结尾时,.readline()返回一个空字符串,但是由于这发生在while line != ''测试之后,您仍然尝试处理这一行

一行一行迭代一个文件的规范(更简单)方法,也就是迭代文件,可以避免这个问题:

for line in test_result_file:
    do_something_with(line)

如果您想去掉结尾的换行符(您的代码就是这样),那么您只需在line上调用.rstrip()

此外,您还需要确保无论发生什么情况,文件都已正确关闭。规范的方法是使用open()作为上下文管理器:

with open("path/to/file.txt") as f:
    for line in test_result_file:
        do_something_with(line)

这将在退出with块时调用f.close(),但是它退出了(无论for循环刚刚完成还是发生了异常)

此外,不必进行复杂的计算来查找管道后面的零件,只需拆分字符串:

for line in test_results_file:
    total = int(line.strip().split("|")[1])
     num_recs += 1

最后,您可以使用stdlib的csv模块来解析您的文件,而不是手动进行解析

更简单的方法

演示:

total = 0
num_recs = 0

with open(filename) as infile:                            #Read File
    for line in infile:                                   #Iterate Each line
        if "|" in line:                                   #Check if | in line
            total += int(line.strip().split("|")[-1])     #Extract value and sum
            num_recs += 1
print(total, num_recs)

因为它不是一个数值。因此,如果python不能将其转换为整数,它就会抛出ValueError。你可以用下面的代码来检查它

def calculate_average():
  test_results_file = open('studentNamesfile.txt', 'r')
  total = 0
  num_recs = 0
  for line in test_results_file.readlines():
    try:
        total += int(line[line.find('|') + 1:])
        num_recs += 1
    except ValueError:
        print("Invalid Data: ", line[line.find('|') + 1:])
  test_results_file.close()
  print("total:", total)
  print("num_recs:", num_recs)
  print("Average:", float(total)/num_recs)

读线与读线

from io import StringIO
s = 'hello\n hi\n how are you\n'
f = StringIO(unicode(s))
l = f.readlines()
print(l)
# OUTPUT: [u'hello\n', u' hi\n', u' how are you\n']

f = StringIO(unicode(s)) 
l1 = f.readline()
# u'hello\n'
l2 = f.readline()
# u' hi\n'
l3 = f.readline()
# u' how are you\n'
l4 = f.readline()
# u''
l5 = f.readline()
# u''

读线

如果我们使用readlines,那么它将返回一个基于\n字符的列表

读线

从上面的代码中我们可以看到,stringIO中只有3行,但是当我们访问readline时,它总是给我们一个空字符串。因此,在您的代码中,您将它转换为整数,因为您将得到ValueError异常

相关问题 更多 >