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