Dovahkiin
Dovahkiin

Reputation: 257

Python - More efficient way of formatting output from reading a file

I have a text file containing the following: (Taking the headings to be: Student ID, Name, Age, Favourite Subject)

1234,Luke,15,History,
1256,Hannah,17,Maths,
1278,Katherine,14,Geography,
1290,Rachael,12,French,
3412,James,16,Computer Science,

What I want to do is output the contents of this file to the user, to look like this:

Student ID    Name          Age    Favourite Subject
1234          Luke          15     History
1256          Hannah        17     Maths
1278          Katherine     14     Geography
1290          Rachael       12     French
3412          James         16     Computer Science       

My current code, shown below, works just fine (it seems to me, at least), but I'm guessing there's a much better way to do it that would be more efficient? It feels like I might have made it more awkward than is necessary, with the appending to lists etc.

def formatOutput():
    headings = ["Student ID", "Name", "Age", "Favourite Subject"]
    formatID = []
    formatName = []
    formatAge = []
    formatFavSub = []


    with open("Students.txt","r") as file:
        for line in file:
            info = line.split(",")
            formatID.append(info[0])
            formatName.append(info[1])
            formatAge.append(info[2])
            formatFavSub.append(info[3])

            formatOutput = [headings] + list(zip(formatID, formatName, formatAge, formatFavSub))


for i in formatOutput:
    print("{:<10}\t{:<9}\t{:<3}\t{:<17}".format(*i)) 

formatOutput()

Help's appreciated. Thanks!

Upvotes: 1

Views: 75

Answers (2)

Roland Smith
Roland Smith

Reputation: 43533

Keeping it simple:

template = "{:<10}\t{:<9}\t{:<3}\t{:<17}"
print(template.format("Student ID", "Name", "Age", "Favourite Subject"))
with open('Students.txt') as studentsfile:
    for line in studentsfile:
        print(template.format(*line.split(',')))

Upvotes: 2

Doug
Doug

Reputation: 3883

I would use the Python csv module reader / writer, or the DictReader / DictWriter.

From the Python csv document:

>>> import csv
>>> with open('eggs.csv', 'rb') as csvfile:
...     spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
...     for row in spamreader:
...         print ', '.join(row)
Spam, Spam, Spam, Spam, Spam, Baked Beans
Spam, Lovely Spam, Wonderful Spam

Since I have time now, I've added a full solution on how I would personally with this code:

import csv

def format_row(data=None, widths=None):
    return '\t'.join([column.ljust(width, ' ')
                    for column, width in zip(data, widths)])

heading = ("Student Id", "Name", "Age", "Favorite Subject")
widths = (10, 9, 3, 17)
output = []

output.append(format_row(heading, widths))

with open('Students.txt', 'r') as f:
    csv = csv.reader(f)
    for row in csv:
        output.append(format_row(row, widths))

for line in output:
    print(line)

The format_row() method uses list comprehension to format the columns with the correct spacing. The zip combines the column with its width. This allows you to format each column accordingly. Also note, in most cases, you would not want to space delimit the file AND add tab delimiters as well. However, I added them since that is how you initially asked the question. Finally, you want to add a check to make sure that you have enough rows and widths. If not, you'll end up with an error.

Upvotes: 1

Related Questions