Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
nice table printing in python
def print_table(items, header=None, wrap=True, max_col_width=20, wrap_style="wrap", row_line=False, fix_col_width=False):
''' Prints a matrix of data as a human readable table. Matrix
should be a list of lists containing any type of values that can
be converted into text strings.
Two different column adjustment methods are supported through
the *wrap_style* argument:
wrap: it will wrap values to fit max_col_width (by extending cell height)
cut: it will strip values to max_col_width
If the *wrap* argument is set to False, column widths are set to fit all
values in each column.
This code is free software. Updates can be found at
https://gist.github.com/jhcepas/5884168
'''
if fix_col_width:
c2maxw = dict([(i, max_col_width) for i in xrange(len(items[0]))])
wrap = True
elif not wrap:
c2maxw = dict([(i, max([len(str(e[i])) for e in items])) for i in xrange(len(items[0]))])
else:
c2maxw = dict([(i, min(max_col_width, max([len(str(e[i])) for e in items])))
for i in xrange(len(items[0]))])
if header:
current_item = -1
row = header
if wrap and not fix_col_width:
for col, maxw in c2maxw.iteritems():
c2maxw[col] = max(maxw, len(header[col]))
if wrap:
c2maxw[col] = min(c2maxw[col], max_col_width)
else:
current_item = 0
row = items[current_item]
while row:
is_extra = False
values = []
extra_line = [""]*len(row)
for col, val in enumerate(row):
cwidth = c2maxw[col]
wrap_width = cwidth
val = str(val)
try:
newline_i = val.index("\n")
except ValueError:
pass
else:
wrap_width = min(newline_i+1, wrap_width)
val = val.replace("\n", " ", 1)
if wrap and len(val) > wrap_width:
if wrap_style == "cut":
val = val[:wrap_width-1]+"+"
elif wrap_style == "wrap":
extra_line[col] = val[wrap_width:]
val = val[:wrap_width]
val = val.ljust(cwidth)
values.append(val)
print ' | '.join(values)
if not set(extra_line) - set(['']):
if header and current_item == -1:
print ' | '.join(['='*c2maxw[col] for col in xrange(len(row)) ])
current_item += 1
try:
row = items[current_item]
except IndexError:
row = None
else:
row = extra_line
is_extra = True
if row_line and not is_extra and not (header and current_item == 0):
if row:
print ' | '.join(['-'*c2maxw[col] for col in xrange(len(row)) ])
else:
print ' | '.join(['='*c2maxw[col] for col in xrange(len(extra_line)) ])
print_table([[3,2, {"whatever":1, "bla":[1,2]}], [5,"this is a test\n of wrapping text\n with the new function",777], [1,1,1]],
header=[ "This is column number 1", "Column number 2", "col3"],
wrap=True, max_col_width=15, wrap_style='wrap',
row_line=True, fix_col_width=True)
# This is column | Column number 2 | col3
# number 1 | |
# =============== | =============== | ===============
# 3 | 2 | {'bla': [1, 2],
# | | 'whatever': 1}
# --------------- | --------------- | ---------------
# 5 | this is a test | 777
# | of |
# | wrapping text |
# | with the new |
# | function |
# --------------- | --------------- | ---------------
# 1 | 1 | 1
# =============== | =============== | ===============
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment