4

I'm looking at Python packages that provide an easy way to make formatted 'pretty' tables as text output. This answer provides a few suggestions. The catch is, I want to print my table sequentially (one row at a time) similar to a logger.

To illustrate, the output of tabulate is perfectly fine for my application:

from tabulate import tabulate   
some_data = [['08:01', 1.00, 32], ['08:02', 1.01, 33], ['08:03', 1.02, 33]]
headers = ['Time', 'x', 'n']
print(tabulate(some_data, headers=headers, tablefmt='plain'))

Output:

Time       x    n
08:01   1      32
08:02   1.01   33
08:03   1.02   33

But I want to do each operation one at a time not all-at-once: 1. print the headers 2. print the first row of data 3. print the next 4. ...etc.

Of course, I tried this:

print(tabulate(some_data[0:1], tablefmt='plain'))

Output:

08:01  1  32

This obviously won't work perfectly because the formatting of each row will be different each time. So I need a package where you can set up the table first (specifying the required formats, column widths, etc). And then output data one row at a time.

Does anyone know if this is possible in one of these packages or another package that I could import?

Bill
  • 10,323
  • 10
  • 62
  • 85
  • Do you have to do it one line at a time? It's easy enough to build a single list of all results, then print that once - unless you want 'real-time' updates as the data is processed? – match Feb 12 '18 at 21:12
  • Yes I want real-time updates of each row. Similar to a logger. One every minute typically. – Bill Feb 12 '18 at 21:14

2 Answers2

3

You can get quite good simple tables just using the builtin python format command. You can specify a format string, then use that as a 'template' and pass in data to be applied to that template.

format_string = "{:<10}{:<8}{:<10}"
print(format_string.format(*headers))
for entry in some_data:
    print(format_string.format(*entry))

For a full list of the various options for padding etc, see https://pyformat.info

match
  • 10,388
  • 3
  • 23
  • 41
  • Thanks. Yes, I know I could write my own code to do it. I would prefer to see if there is an existing package to do it first. Also, the width and number of columns may change each time I run the script so that makes manually setting up the formatting tedious. – Bill Feb 12 '18 at 21:39
  • You should be able to dynamically generate the format string based on the number of columns present in your data - though width is always going to be a guess if you are iterating as you won't know the widest column until you reach it - though header column width might be a good approximation. – match Feb 12 '18 at 21:43
  • Yes I know. In fact it was half-way through writing the code to do that that I thought "hang on, there must be an existing package for this". – Bill Feb 12 '18 at 22:05
1

str.format()

You would be able to use string formatting using .format, as below:

some_data = [['08:01', 1.00, 32], ['08:02', 1.01, 33], ['08:03', 1.02, 33]]
h = ['Time', 'x', 'n']

print('{:<10s} {:<5s} {:<5s}'.format(*h))
for list_ in some_data:
    print('{:<10s} {:.2f} {:<5d}'.format(*list_))

This would then print the following:

Time       x     n
08:01      1.00 32
08:02      1.01 33   
08:03      1.02 33

You can play around with the values inside the curly braces {} to get a more desired output, but this essentially does the job.

More information on string formatting can be found here: https://docs.python.org/3.5/library/string.html

Edit: Used unpacking *

  • Obviously I could write my own code to do it but I'm looking for an existing package. – Bill Feb 12 '18 at 21:37