Search code examples
pythonlisttabular

Printing out a 2D list like a table with Python


I'm trying to print out a 2D list like a table, and I found a piece of code here: Pretty print 2D Python list

But I couldn't understand how it really works, can anyone please explain to me?

s = [[str(e) for e in row] for row in matrix]
lens = [max(map(len, col)) for col in zip(*s)]
fmt = '\t'.join('{{:{}}}'.format(x) for x in lens)
table = [fmt.format(*row) for row in s]
print '\n'.join(table)

Solution

  • As others have commented, there are a lot of concepts going on here (too many to be manageable in a single answer). But for your further study (try out each statement in turn with a (small) example 2D list), here's how it breaks down:

    Turn the data into a list of lists of strings (uses list comprehension):

    s = [[str(e) for e in row] for row in matrix]
    

    Get a list of the maximum number of characters in each column so we know how to format the columns:

    lens = [max(map(len, col)) for col in zip(*s)]
    

    (This one is more complex: zip() here enables us to iterate over the columns of s, passing each to the len() method to find its length (this is achieved with map()); then find the maximum length of each column with the max() builtin.)

    Set up the corresponding Python format strings as tab-separated entries:

    fmt = '\t'.join('{{:{}}}'.format(x) for x in lens)
    

    fmt is now the format specifier for every row, e.g. '{:4}\t{:6}\t{:6}' for three columns with widths 4,6,6 (NB only works on Python 2.7+ because the fields haven't been numbered)

    Set up the table as a list of rows in their string format (use another list comprehension):

    table = [fmt.format(*row) for row in s]
    

    Join the whole lot together in a single string, with rows separated by newlines:

    print '\n'.join(table)
    

    join() takes a list of strings and produces one string with them all joined together by the chosen delimiter (here, \n, the newline character).