tabulate#

tabulate is a module that allows you to display table data beautifully. It is not part of standard Python library, so tabulate needs to be installed:

pip install tabulate

Module supports such tabular data types as:

  • list of lists (in general case - iterable of iterables)

  • dictionary list (or any other iterable object with dictionaries). Keys are used as column names

  • dictionary with iterable objects. Keys are used as column names

Function tabulate() is used to generate table:

In [1]: from tabulate import tabulate

In [2]: sh_ip_int_br = [('FastEthernet0/0', '15.0.15.1', 'up', 'up'),
   ...:  ('FastEthernet0/1', '10.0.12.1', 'up', 'up'),
   ...:  ('FastEthernet0/2', '10.0.13.1', 'up', 'up'),
   ...:  ('Loopback0', '10.1.1.1', 'up', 'up'),
   ...:  ('Loopback100', '100.0.0.1', 'up', 'up')]
   ...:

In [4]: print(tabulate(sh_ip_int_br))
---------------  ---------  --  --
FastEthernet0/0  15.0.15.1  up  up
FastEthernet0/1  10.0.12.1  up  up
FastEthernet0/2  10.0.13.1  up  up
Loopback0        10.1.1.1   up  up
Loopback100      100.0.0.1  up  up
---------------  ---------  --  --

headers#

Parameter headers allows you to pass an additional argument that specifies column names:

In [8]: columns = ['Interface', 'IP', 'Status', 'Protocol']

In [9]: print(tabulate(sh_ip_int_br, headers=columns))
Interface        IP         Status    Protocol
---------------  ---------  --------  ----------
FastEthernet0/0  15.0.15.1  up        up
FastEthernet0/1  10.0.12.1  up        up
FastEthernet0/2  10.0.13.1  up        up
Loopback0        10.1.1.1   up        up
Loopback100      100.0.0.1  up        up

Quite often, the first data set is headers. Then it is enough to specify headers equal to “firstrow”:

In [18]: data
Out[18]:
[('Interface', 'IP', 'Status', 'Protocol'),
 ('FastEthernet0/0', '15.0.15.1', 'up', 'up'),
 ('FastEthernet0/1', '10.0.12.1', 'up', 'up'),
 ('FastEthernet0/2', '10.0.13.1', 'up', 'up'),
 ('Loopback0', '10.1.1.1', 'up', 'up'),
 ('Loopback100', '100.0.0.1', 'up', 'up')]

In [20]: print(tabulate(data, headers='firstrow'))
Interface        IP         Status    Protocol
---------------  ---------  --------  ----------
FastEthernet0/0  15.0.15.1  up        up
FastEthernet0/1  10.0.12.1  up        up
FastEthernet0/2  10.0.13.1  up        up
Loopback0        10.1.1.1   up        up
Loopback100      100.0.0.1  up        up

If data is in the form of a list of dictionaries, you should specify headers equal to “keys”:

In [22]: list_of_dict
Out[22]:
[{'IP': '15.0.15.1',
  'Interface': 'FastEthernet0/0',
  'Protocol': 'up',
  'Status': 'up'},
 {'IP': '10.0.12.1',
  'Interface': 'FastEthernet0/1',
  'Protocol': 'up',
  'Status': 'up'},
 {'IP': '10.0.13.1',
  'Interface': 'FastEthernet0/2',
  'Protocol': 'up',
  'Status': 'up'},
 {'IP': '10.1.1.1',
  'Interface': 'Loopback0',
  'Protocol': 'up',
  'Status': 'up'},
 {'IP': '100.0.0.1',
  'Interface': 'Loopback100',
  'Protocol': 'up',
  'Status': 'up'}]

In [23]: print(tabulate(list_of_dict, headers='keys'))
Interface        IP         Status    Protocol
---------------  ---------  --------  ----------
FastEthernet0/0  15.0.15.1  up        up
FastEthernet0/1  10.0.12.1  up        up
FastEthernet0/2  10.0.13.1  up        up
Loopback0        10.1.1.1   up        up
Loopback100      100.0.0.1  up        up

Dict with lists in values:

In [6]: vlans = {"sw1": [10, 20, 30, 40], "sw2": [1, 2, 10], "sw3": [1, 2, 3, 4, 5, 10, 11, 12]}

In [7]: print(tabulate(vlans, headers="keys"))
  sw1    sw2    sw3
-----  -----  -----
   10      1      1
   20      2      2
   30     10      3
   40             4
                  5
                 10
                 11
                 12

Table style#

tabulate supports different table styles.

Table in Grid format:

In [24]: print(tabulate(list_of_dict, headers='keys', tablefmt="grid"))
+-----------------+-----------+----------+------------+
| Interface       | IP        | Status   | Protocol   |
+=================+===========+==========+============+
| FastEthernet0/0 | 15.0.15.1 | up       | up         |
+-----------------+-----------+----------+------------+
| FastEthernet0/1 | 10.0.12.1 | up       | up         |
+-----------------+-----------+----------+------------+
| FastEthernet0/2 | 10.0.13.1 | up       | up         |
+-----------------+-----------+----------+------------+
| Loopback0       | 10.1.1.1  | up       | up         |
+-----------------+-----------+----------+------------+
| Loopback100     | 100.0.0.1 | up       | up         |
+-----------------+-----------+----------+------------+

Table in Markdown format:

In [25]: print(tabulate(list_of_dict, headers='keys', tablefmt='pipe'))
| Interface       | IP        | Status   | Protocol   |
|:----------------|:----------|:---------|:-----------|
| FastEthernet0/0 | 15.0.15.1 | up       | up         |
| FastEthernet0/1 | 10.0.12.1 | up       | up         |
| FastEthernet0/2 | 10.0.13.1 | up       | up         |
| Loopback0       | 10.1.1.1  | up       | up         |
| Loopback100     | 100.0.0.1 | up       | up         |

Table in HTML format:

In [26]: print(tabulate(list_of_dict, headers='keys', tablefmt='html'))
<table>
<thead>
<tr><th>Interface      </th><th>IP       </th><th>Status  </th><th>Protocol  </th></tr>
</thead>
<tbody>
<tr><td>FastEthernet0/0</td><td>15.0.15.1</td><td>up      </td><td>up        </td></tr>
<tr><td>FastEthernet0/1</td><td>10.0.12.1</td><td>up      </td><td>up        </td></tr>
<tr><td>FastEthernet0/2</td><td>10.0.13.1</td><td>up      </td><td>up        </td></tr>
<tr><td>Loopback0      </td><td>10.1.1.1 </td><td>up      </td><td>up        </td></tr>
<tr><td>Loopback100    </td><td>100.0.0.1</td><td>up      </td><td>up        </td></tr>
</tbody>
</table>

Alignment of columns#

You can specify alignment for columns:

In [27]: print(tabulate(list_of_dict, headers='keys', tablefmt='pipe', stralign='center'))
|    Interface    |    IP     |  Status  |  Protocol  |
|:---------------:|:---------:|:--------:|:----------:|
| FastEthernet0/0 | 15.0.15.1 |    up    |     up     |
| FastEthernet0/1 | 10.0.12.1 |    up    |     up     |
| FastEthernet0/2 | 10.0.13.1 |    up    |     up     |
|    Loopback0    | 10.1.1.1  |    up    |     up     |
|   Loopback100   | 100.0.0.1 |    up    |     up     |

Note that not only columns are displayed centrally, but Markdown syntax has been changed accordingly.

Additional material#

Articles from author tabulate:

Stack Overflow: