How to Create Tables with Python Tabulate Module

Hello everyone! In today's blog post, we're going to explore the Python Tabulate module, an incredibly useful tool I often use in my work. For those of you not familiar with it, Tabulate is a Python library that makes it super easy to convert python data structures into well-formatted tables.

I've personally found that while Tabulate is straightforward for the most part, it can sometimes get a bit tricky, especially when you're jumping between lists and dictionaries to create tables. To help you out, I'm going to walk you through some examples, starting from the very basics and gradually moving to more complex scenarios.

You can install tabulate using the usual pip method of pip install tabulate

Python Unit Testing - What’s the Point?
Unit testing is like giving each small piece of your code a mini-exam to make sure it knows its stuff before it gets to play its part in the bigger picture of your application.

Simple Tabulate Example

In this first example, we're using the Tabulate module to turn a simple list of lists into a neat table. The data variable holds our information - it's a list where each item is another list, representing a row in our table. Each of these inner lists has two elements, a name and an age.

# Import the tabulate module
from tabulate import tabulate

# Sample data: a list of lists
data = [['Alice', 20], ['Bob', 25], ['Charlie', 35]]

# Create a table and print it
print(tabulate(data))
#output
-------  --
Alice    20
Bob      25
Charlie  35
-------  --
  1. We start by importing the tabulate function from the tabulate module.
  2. We then define our data [['Alice', 20], ['Bob', 25], ['Charlie', 35]]. Each inner list represents a person, with their name and age.
  3. Finally, we call print(tabulate(data)). The tabulate function takes our list data, and formats it into a table. We then print this table, which results in a clean, readable output of our data.

Adding a Header Row

from tabulate import tabulate

data = [['Name', 'Age'], ['Alice', 20], ['Bob', 25], ['Charlie', 35]]
print(tabulate(data, headers='firstrow'))
Name       Age
-------  -----
Alice       20
Bob         25
Charlie     35

This example introduces a header row to our table. The data list now starts with a special row, ['Name', 'Age']. This row is intended to be the header of our table, labelling each column.

When we call tabulate(data, headers='firstrow'), we're instructing Tabulate to treat the first row in our data list as the header row. The headers='firstrow' argument is the key addition here. It tells Tabulate, "Hey, use the first row of my data as column headers."

Using Dictionaries with Tabulate

In this next example, we're stepping things up by using a list of dictionaries to create our table with the Tabulate module. Each dictionary in the data list represents a row in the table, with key-value pairs corresponding to column headers and their respective values.

from tabulate import tabulate

# Sample data: a list of dictionaries
data = [
    {"Name": "Alice", "Age": 20, "City": "London"},
    {"Name": "Bob", "Age": 25, "City": "Paris"},
    {"Name": "Charlie", "Age": 35, "City": "New York"}
]

print(tabulate(data, headers="keys"))
Name       Age  City
-------  -----  --------
Alice       20  London
Bob         25  Paris
Charlie     35  New York

In the data variable, we have three dictionaries, each containing keys 'Name', 'Age', and 'City', and their corresponding values for different individuals. This format allows us to include more detailed information for each person in a structured way.

When we use print(tabulate(data, headers="keys")), Tabulate recognizes each key in our dictionaries as a column header. The headers="keys" argument tells Tabulate to automatically use the keys from our dictionaries ('Name', 'Age', 'City') as headers for the columns. This results in a neatly formatted table where each row corresponds to the information of one person, and columns are clearly labelled for easy reading.

Aligning and Formatting Numbers in Tables with Python Tabulate

Up next, let's see how to make numbers in our tables look neat and tidy. We'll use Python's Tabulate module to line up numbers to the right and show prices with just the right amount of decimal points. This is really handy when you're working with things like prices or quantities, and you want everything to be easy to read and compare.

from tabulate import tabulate

# Sample data: a list of dictionaries with numeric values
data = [
    {"Item": "Charger", "Quantity": 15, "Price": 89.2},
    {"Item": "Case", "Quantity": 20, "Price": 19.507},
    {"Item": "Cable", "Quantity": 10, "Price": 1.99}
]

# Create a table with headers, aligning the columns and print it
print(tabulate(data, headers="keys", numalign="right", floatfmt=".2f"))
Item       Quantity    Price
-------  ----------  -------
Charger          15    89.20
Case             20    19.51
Cable            10     1.99


Here, the numalign="right" and floatfmt=".2f" arguments in the tabulate function play key roles in how our data is presented in the table.

  1. numalign="right" - This argument specifies the alignment of numeric columns. By setting it to "right", we ensure that all numeric data in our table is right-aligned.
  2. floatfmt=".2f" - This argument controls the formatting of floating-point numbers. The format string ".2f" means that floating-point numbers will be displayed with two decimal places. This is particularly useful for financial data or any scenario where precision to two decimal places is desired. Our table ensures that the 'Price' column displays each amount consistently with two digits after the decimal point, making the prices formatted.
Python List Slicing (with examples)
In this post, we’re going to explore the basics of list slicing with some straightforward examples. We’ll see how easy it is to slice lists for various needs

Tabulate Table Formats

Now, let's try and change the way our tables appear in Tabulate. We'll use the same data but format it in three distinct ways. Default table, plain text, a neat grid, and a web-ready HTML table. It's interesting to see how a simple change in format can give our data a whole new look.

from tabulate import tabulate

# Sample data: a list of lists
data = [["Name", "Age"],["Alice", 20], ["Bob", 25], ["Charlie", 35]]

# Print the table in different formats
print(tabulate(data, headers="firstrow"))
print(tabulate(data, headers="firstrow", tablefmt="plain"))
print(tabulate(data, headers="firstrow", tablefmt="grid"))
print(tabulate(data, headers="firstrow", tablefmt="html"))
#default
Name       Age
-------  -----
Alice       20
Bob         25
Charlie     35
#Plain
Name       Age
Alice       20
Bob         25
Charlie     35
#Grid
+---------+-------+
| Name    |   Age |
+=========+=======+
| Alice   |    20 |
+---------+-------+
| Bob     |    25 |
+---------+-------+
| Charlie |    35 |
+---------+-------+
#html
<table>
<thead>
<tr><th>Name   </th><th style="text-align: right;">  Age</th></tr>
</thead>
<tbody>
<tr><td>Alice  </td><td style="text-align: right;">   20</td></tr>
<tr><td>Bob    </td><td style="text-align: right;">   25</td></tr>
<tr><td>Charlie</td><td style="text-align: right;">   35</td></tr>
</tbody>
</table>
Name Age
Alice 20
Bob 25
Charlie 35

In the script, the different tablefmt arguments in the tabulate function showcase various table styles.

  1. tablefmt="plain" - Displays the table in a simple text format.
  2. tablefmt="grid" - This format adds grid lines between rows and columns for a more structured look.
  3. tablefmt="HTML" - Generates the table in HTML format, which is useful for web pages or HTML documents.

Row Index

By using the showindex argument, you can add a row index (or serial number) to each row. For instance, showindex="always" will prepend a column with row numbers, making it easier to reference specific rows.

from tabulate import tabulate

data = [
    {"Name": "Alice", "Age": 20, "City": "London"},
    {"Name": "Bob", "Age": 25, "City": "Paris"},
    {"Name": "Charlie", "Age": 35, "City": "New York"}
]

# Create a table with Row Index
print(tabulate(data, headers="keys", showindex="always"))
    Name       Age  City
--  -------  -----  --------
 0  Alice       20  London
 1  Bob         25  Paris
 2  Charlie     35  New York

If you want to use a custom row index, you could do something like this.

from tabulate import tabulate

data = [
    {"Name": "Alice", "Age": 20, "City": "London"},
    {"Name": "Bob", "Age": 25, "City": "Paris"},
    {"Name": "Charlie", "Age": 35, "City": "New York"}
]

# Custom serial numbers
serial_numbers = ['A1', 'B2', 'C3']

# Create a table with custom serial numbers
print(tabulate(data, headers="keys", showindex=serial_numbers))
#output
    Name       Age  City
--  -------  -----  --------
A1  Alice       20  London
B2  Bob         25  Paris
C3  Charlie     35  New York

Closing Up

In conclusion, we've seen how the Python Tabulate module can transform our data into neat, readable tables with various styles and customizations. From simple lists to structured dictionaries, Tabulate handles it all, offering flexibility with formatting, alignment, and presentation. These examples showcase just a glimpse of what you can achieve with this handy tool, proving it to be an invaluable asset for anyone looking to present data clearly and effectively in Python.