How can I pretty-print ASCII tables with Python? [closed] How can I pretty-print ASCII tables with Python? [closed] python python

How can I pretty-print ASCII tables with Python? [closed]


I've read this question long time ago, and finished writing my own pretty-printer for tables: tabulate.

My use case is:

  • I want a one-liner most of the time
  • which is smart enough to figure the best formatting for me
  • and can output different plain-text formats

Given your example, grid is probably the most similar output format:

from tabulate import tabulateprint tabulate([["value1", "value2"], ["value3", "value4"]], ["column 1", "column 2"], tablefmt="grid")+------------+------------+| column 1   | column 2   |+============+============+| value1     | value2     |+------------+------------+| value3     | value4     |+------------+------------+

Other supported formats are plain (no lines), simple (Pandoc simple tables), pipe (like tables in PHP Markdown Extra), orgtbl (like tables in Emacs' org-mode), rst (like simple tables in reStructuredText). grid and orgtbl are easily editable in Emacs.

Performance-wise, tabulate is slightly slower than asciitable, but much faster than PrettyTable and texttable.

P.S. I'm also a big fan of aligning numbers by a decimal column. So this is the default alignment for numbers if there are any (overridable).


Here's a quick and dirty little function I wrote for displaying the results from SQL queries I can only make over a SOAP API. It expects an input of a sequence of one or more namedtuples as table rows. If there's only one record, it prints it out differently.

It is handy for me and could be a starting point for you:

def pprinttable(rows):  if len(rows) > 1:    headers = rows[0]._fields    lens = []    for i in range(len(rows[0])):      lens.append(len(max([x[i] for x in rows] + [headers[i]],key=lambda x:len(str(x)))))    formats = []    hformats = []    for i in range(len(rows[0])):      if isinstance(rows[0][i], int):        formats.append("%%%dd" % lens[i])      else:        formats.append("%%-%ds" % lens[i])      hformats.append("%%-%ds" % lens[i])    pattern = " | ".join(formats)    hpattern = " | ".join(hformats)    separator = "-+-".join(['-' * n for n in lens])    print hpattern % tuple(headers)    print separator    _u = lambda t: t.decode('UTF-8', 'replace') if isinstance(t, str) else t    for line in rows:        print pattern % tuple(_u(t) for t in line)  elif len(rows) == 1:    row = rows[0]    hwidth = len(max(row._fields,key=lambda x: len(x)))    for i in range(len(row)):      print "%*s = %s" % (hwidth,row._fields[i],row[i])

Sample output:

pkid                                 | fkn                                  | npi-------------------------------------+--------------------------------------+----405fd665-0a2f-4f69-7320-be01201752ec | 8c9949b9-552e-e448-64e2-74292834c73e | 05b517507-2a42-ad2e-98dc-8c9ac6152afa | f972bee7-f5a4-8532-c4e5-2e82897b10f6 | 02f960dfc-b67a-26be-d1b3-9b105535e0a8 | ec3e1058-8840-c9f2-3b25-2488f8b3a8af | 1c71b28a3-5299-7f4d-f27a-7ad8aeadafe0 | 72d25703-4735-310b-2e06-ff76af1e45ed | 03b0a5021-a52b-9ba0-1439-d5aafcf348e7 | d81bb78a-d984-e957-034d-87434acb4e97 | 196c36bb7-c4f4-2787-ada8-4aadc17d1123 | c171fe85-33e2-6481-0791-2922267e8777 | 195d0f85f-71da-bb9a-2d80-fe27f7c02fe2 | 226f964c-028d-d6de-bf6c-688d2908c5ae | 1132aa774-42e5-3d3f-498b-50b44a89d401 | 44e31f89-d089-8afc-f4b1-ada051c01474 | 1ff91641a-5802-be02-bece-79bca993fdbc | 33d8294a-053d-6ab4-94d4-890b47fcf70d | 1f3196e15-5b61-e92d-e717-f00ed93fe8ae | 62fa4566-5ca2-4a36-f872-4d00f7abadcf | 1

Example

>>> from collections import namedtuple>>> Row = namedtuple('Row',['first','second','third'])>>> data = Row(1,2,3)>>> dataRow(first=1, second=2, third=3)>>> pprinttable([data]) first = 1second = 2 third = 3>>> pprinttable([data,data])first | second | third------+--------+------    1 |      2 |     3    1 |      2 |     3


For some reason when I included 'docutils' in my google searches I stumbled across texttable, which seems to be what I'm looking for.