HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Right justified table printer function

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
functionjustifiedprintertableright

Problem

A challenge in the beginner book "Automate the boring stuff":

#! Python3

# Table printer
# Takes a list of lists of strings and displays in right-justified table
# assumption is inner lists contain same number items
# each inner list must be printed as a column

the_list = [["a", "bbbbbbbbb", "tttt"],
            ["d", "eeee", "ggggggggggg"],
            ["g", "hhh", "kkkkkkkkkkkkkkkk"]]

def print_table(a_list):
    """
    Prints a 2d list as a right justified table where each column represents
    an inner list 
    """
    rows = len(the_list[0])
    columns = len(the_list)
    column_widths = [0 for i in range(columns)]
    # find longest string in each inner lists(or column)
    for i in range(len(column_widths)):
        longest = 0
        for item in a_list[i]:
            if len(item) > longest:
                longest = len(item)
        column_widths[i] = longest

    # store strings in list
    print_row = ["" for i in range(rows)]
    # iterate over lists to produce strings with correct formatting
    for a in range(rows):
        for i in range(columns):
            print_row[a] = print_row[a] + a_list[i][a].rjust(column_widths[i]
                                                             + 4)
    for item in print_row:
        print(item)

print_table(the_list)

Solution

The way that you find rows and columns is good. You can't iterate through the lists so this approach is good.
However using them for your comprehensions is bad.

The name a_list is not descriptive, and quite poor.
table whilst generic is much better.

Your comprehensions and loops are actually rather poor.
Your comprehensions are used as if you are initialize an array in say C.
But this is Python, not C.

You should also use the builtins. The way you find the longest in a list can be changed to use max instead.
And if you use a comprehension to change all the strings to their length then you could make column_widths a comprehension.

column_widths = [max(len(cell) for cell in column) for column in table]


Your print row is also quite strange.
Instead of print_row[a] = print_row[a] + you should use print_row[a] += but this can be done in a list comprehension too.
As you're joining the items by nothing you can 'wrap' the comprehension with ''.join.
And the comprehension would just be the indexing the table and justifying you're already doing.
This can result in:

print_row = ["" for i in range(rows)]
for row in range(rows):
    print_row[row] = ''.join(
        table[col][row].rjust(column_widths[col])
        for col in range(columns)
    )

for item in print_row:
    print(item)


From this you should notice that there is not much point in adding to a list, if you're just going to print it later anyway.
And so you can merge these two loops together and remove the print_row comprehension.

Also I'd change the rjust call to not add 4 spaces, as that indents the table, which looks kinda ugly.
And you can add a space between each column by using ' '.join instead.
This can result in the function:

def print_table(table):
    rows, columns = len(table[0]), len(table)

    column_widths = [max(len(cell) for cell in column) for column in table]
    for row in range(rows):
        print(' '.join(table[col][row].rjust(column_widths[col]) for col in range(columns)))

Code Snippets

column_widths = [max(len(cell) for cell in column) for column in table]
print_row = ["" for i in range(rows)]
for row in range(rows):
    print_row[row] = ''.join(
        table[col][row].rjust(column_widths[col])
        for col in range(columns)
    )

for item in print_row:
    print(item)
def print_table(table):
    rows, columns = len(table[0]), len(table)

    column_widths = [max(len(cell) for cell in column) for column in table]
    for row in range(rows):
        print(' '.join(table[col][row].rjust(column_widths[col]) for col in range(columns)))

Context

StackExchange Code Review Q#143801, answer score: 6

Revisions (0)

No revisions yet.