Uncategorized

Print tabular data nicely using python

Ever wondered how to print a matrix (ie, a collection of rows and columns with data in it) and have it always nicely aligned? I searched for it and couldn’t find a handy function to do that, so I decided to implement my own, feel free to report any problems with it:

#!/usr/bin/python
# -*- coding: utf-8 -*-

def matrix_to_string(matrix, header=None):
    """
    Return a pretty, aligned string representation of a nxm matrix.

    This representation can be used to print any tabular data, such as
    database results. It works by scanning the lengths of each element
    in each column, and determining the format string dynamically.

    @param matrix: Matrix representation (list with n rows of m elements).
    @param header: Optional tuple or list with header elements to be displayed.
    """
    if type(header) is list:
        header = tuple(header)
    lengths = []
    if header:
        for column in header:
            lengths.append(len(column))
    for row in matrix:
        for column in row:
            i = row.index(column)
            column = str(column)
            cl = len(column)
            try:
                ml = lengths[i]
                if cl > ml:
                    lengths[i] = cl
            except IndexError:
                lengths.append(cl)

    lengths = tuple(lengths)
    format_string = ""
    for length in lengths:
        format_string += "%-" + str(length) + "s "
    format_string += "\n"

    matrix_str = ""
    if header:
        matrix_str += format_string % header
    for row in matrix:
        matrix_str += format_string % tuple(row)

    return matrix_str

if __name__ == "__main__":
 header = ("Word1", "Word2", "Word3")
 rows = [["Heeeeeeeeeeeeeey", "Hey", "Eh"],
         ["Orange", "Nonononono", "Pineapple"],
         ["Egg", "Spam", "Bacon"]]
 result = matrix_to_string(rows, header)
 print result

Executing this program will give you the following result:

Word1            Word2      Word3     
Heeeeeeeeeeeeeey Hey        Eh        
Orange           Nonononono Pineapple
Egg              Spam       Bacon

Update: Fixed the code to work with any input data.

Advertisements

7 thoughts on “Print tabular data nicely using python

  1. The error is because I assumed that the matrix input would be composed only by strings, and not other data types. I have corrected the code a little bit and will repost right now. I tried your example and it works beautifully now:

    >>> print rs
    7839 KING PRESIDENT None 1981-11-17 00:00:00 5000.0 None 10
    7902 FORD ANALYST 7566 1981-12-03 00:00:00 3000.0 None 20
    7369 SMITH CLERK 7902 1980-12-17 00:00:00 800.0 None 20
    7566 JONES MANAGER 7839 1981-04-02 00:00:00 2975.0 None 20
    7499 ALLEN SALESMAN 7698 1981-02-20 00:00:00 1600.0 300.0 30
    7698 BLAKE MANAGER 7839 1981-05-01 00:00:00 2850.0 None 30
    7876 ADAMS CLERK 7788 1987-05-23 00:00:00 1100.0 None 20
    7654 MARTIN SALESMAN 7698 1981-09-28 00:00:00 1250.0 1400.0 30
    7900 JAMES CLERK 7698 1981-12-03 00:00:00 950.0 None 30
    7782 CLARK MANAGER 7839 1981-06-09 00:00:00 2450.0 None 10
    7934 MILLER CLERK 7782 1982-01-23 00:00:00 1300.0 None 10
    7844 TURNER SALESMAN 7698 1981-09-08 00:00:00 1500.0 0.0 30
    7521 WARD SALESMAN 7698 1981-02-22 00:00:00 1250.0 500.0 30
    7788 SCOTT ANALYST 7566 1987-04-19 00:00:00 3000.0 None 20

  2. The resulting code still has a bug — when computing the column widths, it assumes that no two columns in the same row have the same value.

    The correction is to replace

    for column in row:
    i = row.index(column)
    column = str(column)

    With

    for i in range(len(row)):
    column = row[i]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s