Remove the newline character in a list read from a file [duplicate]
I have a simple program that takes an ID number and prints information for the person matching the ID. The information is stored in a .dat file, with one ID number per line.
The problem is that my program is also reading the newline character \n from the file. I have tried the 'name'.split() method, but this doesn't seem to work for a list.
My program:
from time import localtime, strftime
files = open("grades.dat")
request = open("requests.dat", "w")
lists = files.readlines()
grades = []
for i in range(len(lists)):
grades.append(lists[i].split(","))
cont = "y"
while cont == "y" or cont == "Y":
开发者_开发技巧 answer = raw_input("Please enter the Student I.D. of whom you are looking: ")
for i in range(len(grades)):
if answer == grades[i][0]:
print grades[i][1] + ", " + grades[i][2] + (" "*6) + grades[i][0] + (" "*6) + grades[i][3]
time = strftime("%a, %b %d %Y %H:%M:%S", localtime())
print time
print "Exams - " + grades[i][11] + ", " + grades[i][12] + ", " + grades[i][13]
print "Homework - " + grades[i][4] + ", " + grades[i][5] + ", " + grades[i][6] + ", " + grades[i][7] + ", " +grades[i][8] + ", " + grades[i][9] + ", " + grades[i][10]
total = int(grades[i][4]) + int(grades[i][5]) + int(grades[i][6]) + int(grades[i][7]) + int(grades[i][8]) + int(grades[i][9]) + int(grades[i][10]) + int(grades[i][11]) + int(grades[i][12]) + int(grades[i][13])
print "Total points earned - " + str(total)
grade = float(total) / 550
grade = grade * 100
if grade >= 90:
print "Grade: " + str(grade) + ", that is equal to an A."
elif grade >= 80 and grade < 90:
print "Grade: " + str('%.2f' %grade) + ", that is equal to a B."
elif grade >= 70 and grade < 80:
print "Grade: " + str('%.2f' %grade) + ", that is equal to a C."
elif grade >= 60 and grade < 70:
print "Grade: " + str('%.2f' %grade) + ", that is equal to a D."
else:
print "Grade: " + str('%.2f' %grade) + ", that is equal to an F."
request.write(grades[i][0] + " " + grades[i][1] + ", " + grades [i][2] +
" " + time)
request.write("\n")
print
cont = raw_input("Would you like to search again? ")
if cont != "y" or cont != "Y":
print "Goodbye."
str.strip()
returns a string with leading+trailing whitespace removed, .lstrip
and .rstrip
for only leading and trailing respectively.
grades.append(lists[i].rstrip('\n').split(','))
You can use the strip()
function to remove trailing (and leading) whitespace; passing it an argument will let you specify which whitespace:
for i in range(len(lists)):
grades.append(lists[i].strip('\n'))
It looks like you can just simplify the whole block though, since if your file stores one ID per line grades
is just lists
with newlines stripped:
Before
lists = files.readlines()
grades = []
for i in range(len(lists)):
grades.append(lists[i].split(","))
After
grades = [x.strip() for x in files.readlines()]
(the above is a list comprehension)
Finally, you can loop over a list directly, instead of using an index:
Before
for i in range(len(grades)):
# do something with grades[i]
After
for thisGrade in grades:
# do something with thisGrade
You could actually put the newlines to good use by reading the entire file into memory as a single long string and then use them to split that into the list of grades by using the string splitlines()
method which, by default, removes them in the process.
with open("grades.dat") as file:
grades = [line.split(",") for line in file.read().splitlines()]
...
Here are various optimisations and applications of proper Python style to make your code a lot neater. I've put in some optional code using the csv
module, which is more desirable than parsing it manually. I've also put in a bit of namedtuple
goodness, but I don't use the attributes that then provides. Names of the parts of the namedtuple are inaccurate, you'll need to correct them.
import csv
from collections import namedtuple
from time import localtime, strftime
# Method one, reading the file into lists manually (less desirable)
with open('grades.dat') as files:
grades = [[e.strip() for e in s.split(',')] for s in files]
# Method two, using csv and namedtuple
StudentRecord = namedtuple('StudentRecord', 'id, lastname, firstname, something, homework1, homework2, homework3, homework4, homework5, homework6, homework7, exam1, exam2, exam3')
grades = map(StudentRecord._make, csv.reader(open('grades.dat')))
# Now you could have student.id, student.lastname, etc.
# Skipping the namedtuple, you could do grades = map(tuple, csv.reader(open('grades.dat')))
request = open('requests.dat', 'w')
cont = 'y'
while cont.lower() == 'y':
answer = raw_input('Please enter the Student I.D. of whom you are looking: ')
for student in grades:
if answer == student[0]:
print '%s, %s %s %s' % (student[1], student[2], student[0], student[3])
time = strftime('%a, %b %d %Y %H:%M:%S', localtime())
print time
print 'Exams - %s, %s, %s' % student[11:14]
print 'Homework - %s, %s, %s, %s, %s, %s, %s' % student[4:11]
total = sum(int(x) for x in student[4:14])
print 'Total points earned - %d' % total
grade = total / 5.5
if grade >= 90:
letter = 'an A'
elif grade >= 80:
letter = 'a B'
elif grade >= 70:
letter = 'a C'
elif grade >= 60:
letter = 'a D'
else:
letter = 'an F'
if letter = 'an A':
print 'Grade: %s, that is equal to %s.' % (grade, letter)
else:
print 'Grade: %.2f, that is equal to %s.' % (grade, letter)
request.write('%s %s, %s %s\n' % (student[0], student[1], student[2], time))
print
cont = raw_input('Would you like to search again? ')
print 'Goodbye.'
You want the String.strip(s[, chars]) function, which will strip out whitespace characters or whatever characters (such as '\n') you specify in the chars argument.
See http://docs.python.org/release/2.3/lib/module-string.html
精彩评论