MCPcopy Index your code
hub / github.com/astanin/python-tabulate

github.com/astanin/python-tabulate @v0.10.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.10.0 ↗ · + Follow
412 symbols 1,806 edges 10 files 352 documented · 85%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

python-tabulate

Pretty-print tabular data in Python, a library and a command-line utility.

The main use cases of the library are:

  • printing small tables without hassle: just one function call, formatting is guided by the data itself
  • authoring tabular data for lightweight plain-text markup: multiple output formats suitable for further editing or transformation
  • readable presentation of mixed textual and numeric data: smart column alignment, configurable number formatting, alignment by a decimal point

Installation

To install the Python library and the command line utility, run:

pip install tabulate

The command line utility will be installed as tabulate to bin on Linux (e.g. /usr/bin); or as tabulate.exe to Scripts in your Python installation on Windows (e.g. C:\Python39\Scripts\tabulate.exe).

You may consider installing the library only for the current user:

pip install tabulate --user

In this case the command line utility will be installed to ~/.local/bin/tabulate on Linux and to %APPDATA%\Python\Scripts\tabulate.exe on Windows.

To install just the library on Unix-like operating systems:

TABULATE_INSTALL=lib-only pip install tabulate

On Windows:

set TABULATE_INSTALL=lib-only
pip install tabulate

Build status

python-tabulate

Library usage

The module provides just one function, tabulate, which takes a list of lists or another tabular data type as the first argument, and outputs a nicely formatted plain-text table:

>>> from tabulate import tabulate

>>> table = [["Sun",696000,1989100000],["Earth",6371,5973.6],
...          ["Moon",1737,73.5],["Mars",3390,641.85]]
>>> print(tabulate(table))
-----  ------  -------------
Sun    696000     1.9891e+09
Earth    6371  5973.6
Moon     1737    73.5
Mars     3390   641.85
-----  ------  -------------

The following tabular data types are supported:

  • list of lists or another iterable of iterables
  • list or another iterable of dicts (keys as columns)
  • dict of iterables (keys as columns)
  • list of dataclasses (field names as columns)
  • two-dimensional NumPy array
  • NumPy record arrays (names as columns)
  • pandas.DataFrame

Tabulate is a Python3 library.

Headers

The second optional argument named headers defines a list of column headers to be used:

>>> print(tabulate(table, headers=["Planet","R (km)", "mass (x 10^29 kg)"]))
Planet      R (km)    mass (x 10^29 kg)
--------  --------  -------------------
Sun         696000           1.9891e+09
Earth         6371        5973.6
Moon          1737          73.5
Mars          3390         641.85

If headers="firstrow", then the first row of data is used:

>>> print(tabulate([["Name","Age"],["Alice",24],["Bob",19]],
...                headers="firstrow"))
Name      Age
------  -----
Alice      24
Bob        19

If headers="keys", then the keys of a dictionary/dataframe, or column indices are used. It also works for NumPy record arrays and lists of dictionaries or named tuples:

>>> print(tabulate({"Name": ["Alice", "Bob"],
...                 "Age": [24, 19]}, headers="keys"))
Name      Age
------  -----
Alice      24
Bob        19

When data is a list of dictionaries, a dictionary can be passed as headers to replace the keys with other column labels:

>>> print(tabulate([{1: "Alice", 2: 24}, {1: "Bob", 2: 19}],
...                headers={1: "Name", 2: "Age"}))
Name      Age
------  -----
Alice      24
Bob        19

Row Indices

By default, only pandas.DataFrame tables have an additional column called row index. To add a similar column to any other type of table, pass showindex="always" or showindex=True argument to tabulate(). To suppress row indices for all types of data, pass showindex="never" or showindex=False. To add a custom row index column, pass showindex=rowIDs, where rowIDs is some iterable:

>>> print(tabulate([["F",24],["M",19]], showindex="always"))
-  -  --
0  F  24
1  M  19
-  -  --

Table format

There is more than one way to format a table in plain text. The third optional argument named tablefmt defines how the table is formatted.

Supported table formats are:

  • "plain"
  • "simple"
  • "github"
  • "grid"
  • "simple_grid"
  • "rounded_grid"
  • "heavy_grid"
  • "mixed_grid"
  • "double_grid"
  • "fancy_grid"
  • "outline"
  • "simple_outline"
  • "rounded_outline"
  • "heavy_outline"
  • "mixed_outline"
  • "double_outline"
  • "fancy_outline"
  • "pipe"
  • "orgtbl"
  • "asciidoc"
  • "jira"
  • "presto"
  • "pretty"
  • "psql"
  • "rst"
  • "mediawiki"
  • "moinmoin"
  • "youtrack"
  • "html"
  • "unsafehtml"
  • "latex"
  • "latex_raw"
  • "latex_booktabs"
  • "latex_longtable"
  • "textile"
  • "tsv"

plain tables do not use any pseudo-graphics to draw lines:

>>> table = [["spam",42],["eggs",451],["bacon",0]]
>>> headers = ["item", "qty"]
>>> print(tabulate(table, headers, tablefmt="plain"))
item      qty
spam       42
eggs      451
bacon       0

simple is the default format (the default may change in future versions). It corresponds to simple_tables in Pandoc Markdown extensions:

>>> print(tabulate(table, headers, tablefmt="simple"))
item      qty
------  -----
spam       42
eggs      451
bacon       0

github follows the conventions of GitHub flavored Markdown. It corresponds to the pipe format without alignment colons:

>>> print(tabulate(table, headers, tablefmt="github"))
| item   |   qty |
|--------|-------|
| spam   |    42 |
| eggs   |   451 |
| bacon  |     0 |

grid is like tables formatted by Emacs' table.el package. It corresponds to grid_tables in Pandoc Markdown extensions:

>>> print(tabulate(table, headers, tablefmt="grid"))
+--------+-------+
| item   |   qty |
+========+=======+
| spam   |    42 |
+--------+-------+
| eggs   |   451 |
+--------+-------+
| bacon  |     0 |
+--------+-------+

simple_grid draws a grid using single-line box-drawing characters:

>>> print(tabulate(table, headers, tablefmt="simple_grid"))
┌────────┬───────┐
│ item   │   qty │
├────────┼───────┤
│ spam   │    42 │
├────────┼───────┤
│ eggs   │   451 │
├────────┼───────┤
│ bacon  │     0 │
└────────┴───────┘

rounded_grid draws a grid using single-line box-drawing characters with rounded corners:

>>> print(tabulate(table, headers, tablefmt="rounded_grid"))
╭────────┬───────╮
│ item   │   qty │
├────────┼───────┤
│ spam   │    42 │
├────────┼───────┤
│ eggs   │   451 │
├────────┼───────┤
│ bacon  │     0 │
╰────────┴───────╯

heavy_grid draws a grid using bold (thick) single-line box-drawing characters:

>>> print(tabulate(table, headers, tablefmt="heavy_grid"))
┏━━━━━━━━┳━━━━━━━┓
┃ item   ┃   qty ┃
┣━━━━━━━━╋━━━━━━━┫
┃ spam   ┃    42 ┃
┣━━━━━━━━╋━━━━━━━┫
┃ eggs   ┃   451 ┃
┣━━━━━━━━╋━━━━━━━┫
┃ bacon  ┃     0 ┃
┗━━━━━━━━┻━━━━━━━┛

mixed_grid draws a grid using a mix of light (thin) and heavy (thick) lines box-drawing characters:

>>> print(tabulate(table, headers, tablefmt="mixed_grid"))
┍━━━━━━━━┯━━━━━━━┑
│ item   │   qty │
┝━━━━━━━━┿━━━━━━━┥
│ spam   │    42 │
├────────┼───────┤
│ eggs   │   451 │
├────────┼───────┤
│ bacon  │     0 │
┕━━━━━━━━┷━━━━━━━┙

double_grid draws a grid using double-line box-drawing characters:

>>> print(tabulate(table, headers, tablefmt="double_grid"))
╔════════╦═══════╗
║ item   ║   qty ║
╠════════╬═══════╣
║ spam   ║    42 ║
╠════════╬═══════╣
║ eggs   ║   451 ║
╠════════╬═══════╣
║ bacon  ║     0 ║
╚════════╩═══════╝

fancy_grid draws a grid using a mix of single and double-line box-drawing characters:

>>> print(tabulate(table, headers, tablefmt="fancy_grid"))
╒════════╤═══════╕
│ item   │   qty │
╞════════╪═══════╡
│ spam   │    42 │
├────────┼───────┤
│ eggs   │   451 │
├────────┼───────┤
│ bacon  │     0 │
╘════════╧═══════╛

colon_grid is similar to grid but uses colons only to define columnwise content alignment , without whitespace padding, similar the alignment specification of Pandoc grid_tables:

>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]],
...                ["strings", "numbers"], "colon_grid",
...                colalign=["right", "left"]))
+-----------+-----------+
| strings   | numbers   |
+==========:+:==========+
| spam      | 41.9999   |
+-----------+-----------+
| eggs      | 451       |
+-----------+-----------+

outline is the same as the grid format but doesn't draw lines between rows:

>>> print(tabulate(table, headers, tablefmt="outline"))
+--------+-------+
| item   |   qty |
+========+=======+
| spam   |    42 |
| eggs   |   451 |
| bacon  |     0 |
+--------+-------+

simple_outline is the same as the simple_grid format but doesn't draw lines between rows:

>>> print(tabulate(table, headers, tablefmt="simple_outline"))
┌────────┬───────┐
│ item   │   qty │
├────────┼───────┤
│ spam   │    42 │
│ eggs   │   451 │
│ bacon  │     0 │
└────────┴───────┘

rounded_outline is the same as the rounded_grid format but doesn't draw lines between rows:

>>> print(tabulate(table, headers, tablefmt="rounded_outline"))
╭────────┬───────╮
│ item   │   qty │
├────────┼───────┤
│ spam   │    42 │
│ eggs   │   451 │
│ bacon  │     0 │
╰────────┴───────╯

heavy_outline is the same as the heavy_grid format but doesn't draw lines between rows:

>>> print(tabulate(table, headers, tablefmt="heavy_outline"))
┏━━━━━━━━┳━━━━━━━┓
┃ item   ┃   qty ┃
┣━━━━━━━━╋━━━━━━━┫
┃ spam   ┃    42 ┃
┃ eggs   ┃   451 ┃
┃ bacon  ┃     0 ┃
┗━━━━━━━━┻━━━━━━━┛

mixed_outline is the same as the mixed_grid format but doesn't draw lines between rows:

>>> print(tabulate(table, headers, tablefmt="mixed_outline"))
┍━━━━━━━━┯━━━━━━━┑
│ item   │   qty │
┝━━━━━━━━┿━━━━━━━┥
│ spam   │    42 │
│ eggs   │   451 │
│ bacon  │     0 │
┕━━━━━━━━┷━━━━━━━┙

double_outline is the same as the double_grid format but doesn't draw lines between rows:

>>> print(tabulate(table, headers, tablefmt="double_outline"))
╔════════╦═══════╗
║ item   ║   qty ║
╠════════╬═══════╣
║ spam   ║    42 ║
║ eggs   ║   451 ║
║ bacon  ║     0 ║
╚════════╩═══════╝

fancy_outline is the same as the fancy_grid format but doesn't draw lines between rows:

>>> print(tabulate(table, headers, tablefmt="fancy_outline"))
╒════════╤═══════╕
│ item   │   qty │
╞════════╪═══════╡
│ spam   │    42 │
│ eggs   │   451 │
│ bacon  │     0 │
╘════════╧═══════╛

presto is like tables formatted by Presto cli:

>>> print(tabulate(table, headers, tablefmt="presto"))
 item   |   qty
--------+-------
 spam   |    42
 eggs   |   451
 bacon  |     0

pretty attempts to be close to the format emitted by the PrettyTables library:

>>> print(tabulate(table, headers, tablefmt="pretty"))
+-------+-----+
| item  | qty |
+-------+-----+
| spam  | 42  |
| eggs  | 451 |
| bacon |  0  |
+-------+-----+

psql is like tables formatted by Postgres' psql cli:

>>> print(tabulate(table, headers, tablefmt="psql"))
+--------+-------+
| item   |   qty |
|--------+-------|
| spam   |    42 |
| eggs   |   451 |
| bacon  |     0 |
+--------+-------+

pipe follows the conventions of PHP Markdown Extra extension. It corresponds to pipe_tables in Pandoc. This format uses colons to indicate column alignment:

>>> print(tabulate(table, headers, tablefmt="pipe"))
| item   |   qty |
|:-------|------:|
| spam   |    42 |
| eggs   |   451 |
| bacon  |     0 |

asciidoc formats data like a simple table of the AsciiDoctor format:

>>> print(tabulate(table, headers, tablefmt="asciidoc"))
[cols="<8,>7",options="header"]
|====
| item   |   qty
| spam   |    42
| eggs   |   451
| bacon  |     0
|====

orgtbl follows the conventions of Emacs org-mode, and is editable also in the minor orgtbl-mode. Hence its name:

>>> print(tabulate(table, headers, tablefmt="orgtbl"))
| item   |   qty |
|--------+-------|
| spam   |    42 |
| eggs   |   451 |
| bacon  |     0 |

jira follows the conventions of Atlassian Jira markup language:

>>> print(tabulate(table, headers, tablefmt="jira"))
|| item   ||   qty ||
| spam   |    42 |
| eggs   |   451 |
| bacon  |     0 |

rst formats data like a simple table of the reStructuredText format:

>>> print(tabulate(table, headers, tablefmt="rst"))
======  =====
item      qty
======  =====
spam       42
eggs      451
bacon       0
======  =====

mediawiki format produces a table markup used in Wikipedia and on other MediaWiki-based sites:

```pycon

print(tabulate(table, headers, tablefmt="mediawiki")) {| class="wikitable" style="text-align: left;" |+ |- ! item !! style="text-align: right;"| qty |- | spam || style="text-align: right;"| 42 |- | eggs || style="text-align: right;

Core symbols most depended-on inside this repo

assert_equal
called by 315
test/common.py
tabulate
called by 284
tabulate/__init__.py
_len
called by 12
tabulate/__init__.py
_strip_ansi
called by 8
tabulate/__init__.py
assert_in
called by 7
test/common.py
_expand_iterable
called by 6
tabulate/__init__.py
_append_line
called by 5
tabulate/__init__.py
_is_separating_line
called by 4
tabulate/__init__.py

Shape

Function 398
Method 10
Class 4

Languages

Python100%

Modules by API surface

test/test_output.py199 symbols
tabulate/__init__.py75 symbols
test/test_regression.py44 symbols
test/test_input.py33 symbols
test/test_internal.py22 symbols
test/test_textwrapper.py16 symbols
test/test_cli.py13 symbols
test/common.py5 symbols
test/test_api.py4 symbols
benchmark/benchmark.py1 symbols

For agents

$ claude mcp add python-tabulate \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact