Python PrettyTable: Create, Format, and Sort Tables
python prettytable create format and sort tables: Learn to create, format, and sort tables with Python's PrettyTable library. Covers installation, row handling, alignm...
python prettytable create format and sort tables requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.
When you need to display tabular data in a terminal or log file, Python's prettytable library turns plain lists into readable, aligned tables. This article shows how to create, format, and sort tables using prettytable, covering the API from basic row insertion to column alignment and sorting behavior.
Installing and Importing PrettyTable
prettytable is a third-party package, so install it with pip:
pip install prettytable
Then import the PrettyTable class in your script:
from prettytable import PrettyTable
The library works with Python 3.6 and later. It has no required dependencies, which makes it a lightweight choice for CLI tools and reporting scripts.
Creating a Table and Adding Rows
Instantiate a PrettyTable object and define column names. Rows are added with the add_row method, which expects a list of values in the same order as the columns.
table = PrettyTable() table.field_names = ["Name", "Role", "Years"] table.add_row(["Alice", "Engineer", 5]) table.add_row(["Bob", "Manager", 8]) table.add_row(["Carol", "Designer", 3])
Calling print(table) produces a formatted ASCII table with borders and headers. The field_names attribute defines the header row and the number of columns. Every add_row call must supply the same number of values; otherwise, prettytable raises a ValueError.
Formatting Columns and Alignment
By default, text columns are left-aligned and numeric columns are right-aligned. You can override this per column using the align attribute, which accepts "l", "c", or "r" for left, center, and right.
table.align["Name"] = "c" table.align["Role"] = "l" table.align["Years"] = "r"
Column width is computed automatically from the longest cell, but you can set a minimum width with min_width:
table.min_width["Name"] = 10
For long values, max_width truncates cells and adds an ellipsis. This is useful when you want to keep terminal output compact.
Sorting Rows by a Column
The sortby attribute defines the column used for sorting, and reversesort toggles descending order. Sorting is performed on the string representation of each cell unless you provide a custom sort_key function.
table.sortby = "Years" table.reversesort = True
This sorts the table by the Years column in descending order. To sort by multiple columns, you can pass a tuple to sortby:
table.sortby = ("Role", "Name")
The tuple order determines priority. Sorting is stable, so rows with equal keys retain their original relative order.
Customizing Table Style and Borders
prettytable provides several built-in styles via set_style. For example, Style.MARKDOWN produces Markdown-compatible tables, and Style.PLAIN_COLUMNS removes all borders.
from prettytable import Style table.set_style(Style.MARKDOWN) print(table)
You can also control individual border characters by modifying table.horizontal_char, table.vertical_char, and table.junction_char. This is useful when you need to match a specific output format or embed the table in a plain-text document.
Handling Large Data and Performance
prettytable stores all rows in memory, so it is not suitable for streaming millions of records. For large datasets, consider writing rows incrementally to a file or using a generator with add_rows, which accepts an iterable of row lists.
rows = ([i, i**2] for i in range(1000)) table.add_rows(rows)
Sorting is O(n log n) and happens when you access the string representation, not when you set sortby. If you need to sort before adding rows, use Python's built-in sorted on the data first to avoid repeated sorting overhead.
Common Pitfalls and Compatibility Notes
One frequent mistake is mixing types in a column. prettytable converts all values to strings for display, but sorting uses the original values only if you provide a sort_key. For numeric sorting, pass sort_key=lambda x: float(x) when the column contains strings.
Another issue is that field_names must be set before adding rows. Changing it later resets the table structure and may discard existing rows. If you need dynamic columns, build the table with all columns upfront or recreate it.
prettytable is not thread-safe. If multiple threads write to the same table instance, wrap modifications in a lock or create separate tables per thread and merge them afterward. For most CLI scripts this is not a concern, but it matters in concurrent reporting pipelines.