簡體   English   中英

為什么用內置int()讀取.txt文件中的行的一部分拋出ValueError?

[英]Why throw ValueError with int() builtin reading parts of lines from .txt file?

這是從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:] line[line.find('|') + 1:]它具有正確的值(例如10)。 print(line[line.find('|') + 1:]在上一行,怎么了?

更新 :我正在考慮line[line.find('|') + 1:]包含換行符的可能性,這會破壞int() 但是使用line[line.find('|') + 1:line.find('\\\\')]不能解決問題-引發相同的錯誤。

因為它不是數字值。 因此,如果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方法

如果我們使用readlines ,它將返回一個基於\\n字符的列表。

的ReadLine

從上面的代碼中,我們可以看到stringIO只有3行,但是當我們訪問readline ,它將始終為我們提供一個空字符串。 因此,在您的代碼中,您將其轉換為整數,因為您遇到了ValueError異常。

這里:

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

當您到達文件末尾時, .readline()返回一個空字符串,但是由於這是 while line != ''測試之后發生的,因此您仍然嘗試處理此行。

逐行遍歷文件的規范(且更為簡單)的方法(即遍歷文件)可以避免此問題:

for line in test_result_file:
    do_something_with(line)

如果您想擺脫結尾的換行符(您的代碼就是這種情況.rstrip().rstrip()需要在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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM