How to Install tabulate in Python

v0.10.0 CLI & Utilities Python >=3.10

Pretty-print tabular data

Install pip install tabulate

What is tabulate?

Pretty-print tabular data

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: The command line utility will be installed as to on Linux (e.g. ); or as to in your Python installation on Windows (e.g. ). You may consider installing the library only for the current user: In this case the command line utility will be installed to on Linux and to on Windows. To install just the library on Unix-like operating systems: On Windows: Build status

The module provides just one function, , which takes a list of lists or another tabular data type as the first argument, and outputs a nicely formatted plain-text table: 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 defines a list of column headers to be used: If , then the first row of data is used: If , 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: When data is a list of dictionaries, a dictionary can be passed as to replace the keys with other column labels: 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 or argument to . To suppress row indices for all types of data, pass or . To add a custom row index column, pass , where is some iterable: Table format There is more than one way to format a table in plain text. The third optional argument named 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" tables do not use any pseudo-graphics to draw lines: is the default format (the default may change in future versions). It corresponds to in Pandoc Markdown extensions: follows the conventions of GitHub flavored Markdown. It corresponds to the format without alignment colons: is like tables formatted by Emacs' table.el package. It corresponds to in Pandoc Markdown extensions: draws a grid using single-line box-drawing characters: >>> print(tabulate(table, headers, tablefmt="simplegrid")) ┌────────┬───────┐ │ item │ qty │ ├────────┼───────┤ │ spam │ 42 │ ├────────┼───────┤ │ eggs │ 451 │ ├────────┼───────┤ │ bacon │ 0 │ └────────┴───────┘ draws a grid using single-line box-drawing characters with rounded corners: >>> print(tabulate(table, headers, tablefmt="roundedgrid")) ╭────────┬───────╮ │ item │ qty │ ├────────┼───────┤ │ spam │ 42 │ ├────────┼───────┤ │ eggs │ 451 │ ├────────┼───────┤ │ bacon │ 0 │ ╰────────┴───────╯ draws a grid using bold (thick) single-line box-drawing characters: >>> print(tabulate(table, headers, tablefmt="heavygrid")) ┏━━━━━━━━┳━━━━━━━┓ ┃ item ┃ qty ┃ ┣━━━━━━━━╋━━━━━━━┫ ┃ spam ┃ 42 ┃ ┣━━━━━━━━╋━━━━━━━┫ ┃ eggs ┃ 451 ┃ ┣━━━━━━━━╋━━━━━━━┫ ┃ bacon ┃ 0 ┃ ┗━━━━━━━━┻━━━━━━━┛ draws a grid using a mix of light (thin) and heavy (thick) lines box-drawing characters: >>> print(tabulate(table, headers, tablefmt="mixedgrid")) ┍━━━━━━━━┯━━━━━━━┑ │ item │ qty │ ┝━━━━━━━━┿━━━━━━━┥ │ spam │ 42 │ ├────────┼───────┤ │ eggs │ 451 │ ├────────┼───────┤ │ bacon │ 0 │ ┕━━━━━━━━┷━━━━━━━┙ draws a grid using double-line box-drawing characters: >>> print(tabulate(table, headers, tablefmt="doublegrid")) ╔════════╦═══════╗ ║ item ║ qty ║ ╠════════╬═══════╣ ║ spam ║ 42 ║ ╠════════╬═══════╣ ║ eggs ║ 451 ║ ╠════════╬═══════╣ ║ bacon ║ 0 ║ ╚════════╩═══════╝ draws a grid using a mix of single and double-line box-drawing characters: is similar to but uses colons only to define columnwise content alignment , without whitespace padding, similar the alignment specification of Pandoc : >>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], ... ["strings", "numbers"], "colongrid", ... colalign=["right", "left"])) +-----------+-----------+ | strings | numbers | +==========:+:==========+ | spam | 41.9999 | +-----------+-----------+ | eggs | 451 | +-----------+-----------+ is the same as the format but doesn't draw lines between rows: >>> print(tabulate(table, headers, tablefmt="outline")) +--------+-------+ | item | qty | +========+=======+ | spam | 42 | | eggs | 451 | | bacon | 0 | +--------+-------+ is the same as the format but doesn't draw lines between rows: >>> print(tabulate(table, headers, tablefmt="simpleoutline")) ┌────────┬───────┐ │ item │ qty │ ├────────┼───────┤ │ spam │ 42 │ │ eggs │ 451 │ │ bacon │ 0 │ └────────┴───────┘ is the same as the format but doesn't draw lines between rows: >>> print(tabulate(table, headers, tablefmt="roundedoutline")) ╭────────┬───────╮ │ item │ qty │ ├────────┼───────┤ │ spam │ 42 │ │ eggs │ 451 │ │ bacon │ 0 │ ╰────────┴───────╯ is the same as the format but doesn't draw lines between rows: >>> print(tabulate(table, headers, tablefmt="heavyoutline")) ┏━━━━━━━━┳━━━━━━━┓ ┃ item ┃ qty ┃ ┣━━━━━━━━╋━━━━━━━┫ ┃ spam ┃ 42 ┃ ┃ eggs ┃ 451 ┃ ┃ bacon ┃ 0 ┃ ┗━━━━━━━━┻━━━━━━━┛ is the same as the format but doesn't draw lines between rows: >>> print(tabulate(table, headers, tablefmt="mixedoutline")) ┍━━━━━━━━┯━━━━━━━┑ │ item │ qty │ ┝━━━━━━━━┿━━━━━━━┥ │ spam │ 42 │ │ eggs │ 451 │ │ bacon │ 0 │ ┕━━━━━━━━┷━━━━━━━┙ is the same as the format but doesn't draw lines between rows: >>> print(tabulate(table, headers, tablefmt="doubleoutline")) ╔════════╦═══════╗ ║ item ║ qty ║ ╠════════╬═══════╣ ║ spam ║ 42 ║ ║ eggs ║ 451 ║ ║ bacon ║ 0 ║ ╚════════╩═══════╝ is the same as the format but doesn't draw lines between rows: >>> print(tabulate(table, headers, tablefmt="fancyoutline")) ╒════════╤═══════╕ │ item │ qty │ ╞════════╪═══════╡ │ spam │ 42 │ │ eggs │ 451 │ │ bacon │ 0 │ ╘════════╧═══════╛ is like tables formatted by Presto cli: attempts to be close to the format emitted by the PrettyTables library: is like tables formatted by Postgres' psql cli: follows the conventions of PHP Markdown Extra extension. It corresponds to in Pandoc. This format uses colons to indicate column alignment: formats data like a simple table of the AsciiDoctor format: follows the conventions of Emacs org-mode, and is editable also in the minor orgtbl-mode. Hence its name: follows the conventions of Atlassian Jira markup language: formats data like a simple table of the reStructuredText format: format produces a table markup used in Wikipedia and on other MediaWiki-based sites: format produces a table markup used in MoinMoin wikis: format produces a table markup used in Youtrack tickets: format produces a table markup used in Textile format: produces standard HTML markup as an html.escape'd str with a .reprhtml method so that Jupyter Lab and Notebook display the HTML and a .str property so that the raw HTML remains accessible. table format can be used if an unescaped HTML is required: format creates a environment for LaTeX markup, replacing special characters like `\` to their LaTeX correspondents: behaves like but does not escape LaTeX commands and special characters. creates a environment for LaTeX markup using spacing and style from the package. creates a table that can stretch along multiple pages, using the package. Column alignment is smart about column alignment. It detects columns which contain only numbers, and aligns them by a decimal point (or flushes them to the right if they appear to be integers). Text columns are flushed to the left. You can override the default alignment with and named arguments. Possible column alignments are: , , , (only for numbers), and (to disable alignment). Aligning by a decimal point works best when you need to compare numbers at a glance: Compare this with a more common right alignment: For , anything which can be parsed as a number is a number. Even numbers represented as strings are aligned properly. This feature comes in handy when reading a mixed table of text and numbers from a file: To disable this feature use . Custom column alignment allows a custom column alignment to override the smart alignment described above. Use to define a global setting. Possible alignments are: , , , (only for numbers). Furthermore, you can define for column-specific alignment as a list or a tuple. Possible values are (keeps global setting), , , , (only for numbers), (to disable alignment). Missing alignments are treated as . Custom header alignment Headers' alignment can be defined separately from columns'. Like for columns, you can use: - to define a header-specific global alignment setting. Possible values are , , , (to follow column alignment), - list or tuple to further specify header-wise alignment. Possible values are (keeps global setting), (follow column alignment), , , , (to disable alignment). Missing alignments are treated as . Number formatting allows to define custom number formatting applied to all columns of decimal numbers. Use named argument: argument can be a list or a tuple of format strings, one per column, in which case every column may have different number formatting: works similarly for integers >>> print(tabulate([["a",1000],["b",90000]], intfmt=",")) - ------ a 1,000 b 90,000 - ------ Type Deduction and Missing Values When sees numerical data (with our without comma separators), it attempts to align the column on the decimal point. However, if it observes non-numerical data in the column, it aligns it to the left by default. If data is missing in a column (either None or empty values), the remaining data in the column is used to infer the type: The deduced type (eg. str, float) influences the rendering of any types that have alternative representations. For example, since has methods and defined (and hence is convertible to a and also has a representation), the appropriate representation is selected for the column's deduced type. In order to not lose precision accidentally, types having both an and representation will be considered a . Therefore, if your table contains types convertible to int/float but you'd prefer they be represented as strings, or your strings might all look like numbers such as "1e23": either convert them to the desired representation before you , or ensure that the column always contains at least one other . Text formatting By default, removes leading and trailing whitespace from text columns. To disable whitespace removal, pass . Older versions of the library used a global module-level flag PRESERVEWHITESPACE. Wide (fullwidth CJK) symbols To properly align tables which contain wide characters (typically fullwidth glyphs from Chinese, Japanese or Korean languages), the user should install library. To install it together with : Wide character support is enabled automatically if library is already installed. To disable wide characters support without uninstalling , set the global module-level flag : Multiline cells Most table formats support multiline cell text (text containing newline characters). The newline characters are honored as line break characters. Multiline cells are supported for data rows and for header rows. Further automatic line breaks are not inserted. Of course, some output formats such as latex or html handle automatic formatting of the cell content on their own, but for those that don't, the newline characters in the input cell text are the only means to break a line in cell text. Note that some output formats (e.g. simple, or plain) do not represent row delimiters, so that the representation of multiline cells in such formats may be ambiguous to the reader. The following examples of formatted output use the following table with a multiline cell, and headers with a multiline cell: tables: tables: tables: tables: tables: tables: tables: tables: tables: tables: tables: Multiline cells are not well-supported for the other table formats. Automating Multilines While tabulate supports data passed in with multilines entries explicitly provided, it also provides some support to help manage this work internally. The argument is a list where each entry specifies the max width for it's respective column. Any cell that will exceed this will automatically wrap the content. To assign the same max width for all columns, a singular int scaler can be used. Use for any columns where an explicit maximum does not need to be provided, and thus no automate multiline wrapping will take place. The wrapping uses the python standard textwrap.wrap function with default parameters - aside from width. This example demonstrates usage of automatic multiline wrapping, though typically the lines being wrapped would probably be significantly longer than this. Text is preferably wrapped on whitespaces and right after the hyphens in hyphenated words. breaklongwords (default: True) If true, then words longer than width will be broken in order to ensure that no lines are longer than width. If it is false, long words will not be broken, and some lines may be longer than width. (Long words will be put on a line by themselves, in order to minimize the amount by which width is exceeded.) breakonhyphens (default: True) If true, wrapping will occur preferably on whitespaces and right after hyphens in compound words, as it is customary in English. If false, only whitespaces will be considered as potentially good places for line breaks. Adding Separating lines One might want to add one or more separating lines to highlight different sections in a table. The separating lines will be of the same type as the one defined by the specified formatter as either the linebetweenrows, linebelowheader, linebelow, lineabove or just a simple empty line when none is defined for the formatter >>> from tabulate import tabulate, SEPARATINGLINE table = [["Earth",6371], ["Mars",3390], SEPARATINGLINE, ["Moon",1737]] print(tabulate(table, tablefmt="simple")) ----- ---- Earth 6371 Mars 3390 ----- ---- Moon 1737 ----- ---- ANSI support ANSI escape codes are non-printable byte sequences usually used for terminal operations like setting color output or modifying cursor positions. Because multi-byte ANSI sequences are inherently non-printable, they can still introduce unwanted extra length to strings. For example: >>> len('\033[31mthis text is red\033[0m') # printable length is 16 25 To deal with this, string lengths are calculated after first removing all ANSI escape sequences. This ensures that the actual printable length is used for column widths, rather than the byte length. In the final, printable table, however, ANSI escape sequences are not removed so the original styling is preserved. Some terminals support a special grouping of ANSI escape sequences that are intended to display hyperlinks much in the same way they are shown in browsers. These are handled just as mentioned before: non-printable ANSI escape sequences are removed prior to string length calculation. The only difference with escaped hyperlinks is that column width will be based on the length of the URL text rather than the URL itself (terminals would show this text). For example: >>> len('\x1b]8;; # display length is 7, showing 'example' 40 Usage of the command line utility

Quick Start

Minimal example to get started with tabulate:

from tabulate import tabulate

data = [["Alice", 30, "Engineer"], ["Bob", 25, "Designer"]]
headers = ["Name", "Age", "Role"]
print(tabulate(data, headers=headers, tablefmt="grid"))

Installation

pip (standard)

pip install tabulate

Virtual environment (recommended)

python -m venv venv
source venv/bin/activate   # Windows: venv\Scripts\activate
pip install tabulate

pip3

pip3 install tabulate

conda

conda install -c conda-forge tabulate

Poetry

poetry add tabulate

Verify the Installation

After installing, confirm the package is available:

python -c "import tabulate; print(tabulate.__version__)"

If this prints a version number, installation succeeded. If you see a ModuleNotFoundError, see the errors section below.

Installation Errors

Common errors when installing tabulate with pip.

ModuleNotFoundError: No module named 'tabulate'

Cause: The package is not installed in the current Python environment.

Fix: Run pip install tabulate. If using a virtual environment, ensure it is activated first.

ModuleNotFoundError: No module named 'tabulate' (installed but still failing)

Cause: pip installed the package into a different Python than the one running your script.

Fix: Use python -m pip install tabulate to install into the interpreter you are running.

ImportError: cannot import name 'X' from 'tabulate'

Cause: The function or class does not exist in the installed version.

Fix: Check the version with pip show tabulate and upgrade with pip install --upgrade tabulate.

pip: command not found

Cause: pip is not in PATH or Python was not added to PATH during installation.

Fix: Try python -m pip install tabulate. On macOS/Linux try pip3.

PermissionError: [Errno 13] Permission denied

Cause: No write access to the system Python package directory.

Fix: Use a virtual environment, or add --user: pip install --user tabulate

SSL: CERTIFICATE_VERIFY_FAILED

Cause: pip cannot verify PyPI's SSL certificate — common behind corporate proxies.

Fix: Try: pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org tabulate

Recent Releases

VersionReleased
0.10.0 latest 2026-03-04
0.9.0 2022-10-06
0.8.10 2022-06-21
0.8.9 2021-02-22
0.8.8 2021-02-18

Full release history on PyPI →

Manage tabulate

Upgrade to latest version

pip install --upgrade tabulate

Install a specific version

pip install tabulate==0.10.0

Uninstall

pip uninstall tabulate

Check what is installed

pip show tabulate

Last updated: 2026-04-11 • Data from PyPI