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?).

import locale
locale.setlocale(locale.LC_NUMERIC, "")

def format_num(num):
    """Format a number according to given places.
    Adds commas, etc. Will truncate floats into ints!"
""

    try:
        inum = int(num)
        return locale.format("%.*f", (0, inum), True)

    except (ValueError, TypeError):
        return str(num)

Next, 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.

def get_max_width(table, index):
    """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, StringIO(), 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>

def pprint_table(out, table):
    """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[0])):
        col_paddings.append(get_max_width(table, i))

    for row in table:
        # left col
        print >> out, row[0].ljust(col_paddings[0] + 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.

if __name__ == "__main__":
    table = [["", "taste", "land speed", "life"],
        ["spam", 300101, 4, 1003],
        ["eggs", 105, 13, 42],
        ["lumberjacks", 13, 105, 10]]

    import sys
    out = sys.stdout
    pprint_table(out, table)

The output:

                 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.

7 comments to Pretty-printing a table in Python

  • Vinicius Ruoso

    Hello,

    I work in a Federal University, and here we implements a huge system for 1.300.000 students of public schools.

    I see you module, and add it to one of my programs. But theres something that I can’t change. I want to align the text inside the table at left. Actualy its align on the right.

    Can you help me on this?
    Thanks a lot

    Vinicius

  • Vinicius Ruoso

    Sorry,

    Just solve it.

    Thanks a lot
    Very nice module

  • Hi Vinicius — glad to hear you solved your problem. I guess it would make the code more flexible to enable configuration of the justification style.

  • Vinicius Ruoso

    Yeah, its possible. I just change one caracter to get the expected out.
    Thanks again

  • duke

    i used your module and the result looked very nice. Thanks a lot.

    Duke

  • Robert

    Another thing (and maybe Python has a module that does this) is to print pretty tables:

    +—————————————-+
    | | taste | land speed | life |
    +—————————————-+
    | data | | | |
    | data | | | |
    | data | | | |
    +—————————————-+

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>