Pretty-printing a table in Python
Often you'll have a table of data. You want to print it out as text, but aligned for readability. Here is a simple module to do that. I'll discuss the code below.
First, we have
format_num. This basically just adds commas to our numbers (we want it to be pretty, right?).
"""Format a number according to given places.
Adds commas, etc. Will truncate floats into ints!"""
inum = int(num)
return locale.format("%.*f", (0, inum), True)
except (ValueError, TypeError):
get_max_width gives us the maximum width of a given column in the table. We'll use this when we decide how much to pad each column.
"""Get the maximum width of the given column index"""
return max([len(format_num(row[index])) for row in table])
Finally, the money function. Note that I pass in the output stream — this makes the function more versatile (we could print to a file,
stdout, etc.). It also makes it easier to unit test. We could have done this behind the scenes by redirecting
sys.stdout, but that would be unpythonic! <G>
"""Prints out a table of data, padded for alignment
@param out: Output stream (file-like object)
@param table: The table to print. A list of lists.
Each row must have the same number of columns. """
col_paddings = 
for i in range(len(table)):
for row in table:
# left col
print >> out, row.ljust(col_paddings + 1),
# rest of the cols
for i in range(1, len(row)):
col = format_num(row[i]).rjust(col_paddings[i] + 2)
print >> out, col,
print >> out
And we top it off with a bit of test code.
table = [["", "taste", "land speed", "life"],
["spam", 300101, 4, 1003],
["eggs", 105, 13, 42],
["lumberjacks", 13, 105, 10]]
out = sys.stdout
taste land speed life spam 300,101 4 1,003 eggs 105 13 42 lumberjacks 13 105 10
The linked zip file has unit tests that exercise the code a bit more thoroughly.