patternpythonMinor
Right justified table printer function
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
However using them for your comprehensions is bad.
The name
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
And if you use a comprehension to change all the strings to their length then you could make
Your print row is also quite strange.
Instead of
As you're joining the items by nothing you can 'wrap' the comprehension with
And the comprehension would just be the indexing the table and justifying you're already doing.
This can result in:
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
Also I'd change the
And you can add a space between each column by using
This can result in the function:
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.