Make ASCII Table (Python)

An adapted version of a similar stack-overflow answer.

The primary tweaks made are to ensure the columns actually take the width of values into account

Accepts two lists

  • columns - List of column names to print
  • data - list of dicts, with the keys in the dicts corresponding to the column names specified in columns

Any keys present in data which haven't been specified in columns are ignored

Details

Snippet

# Adapted From http://stackoverflow.com/questions/5909873/how-can-i-pretty-print-ascii-tables-with-python
def make_table(columns, data):
    """Create an ASCII table and return it as a string.

    Pass a list of strings to use as columns in the table and a list of
    dicts. The strings in 'columns' will be used as the keys to the dicts in
    'data.'

    """
    # Calculate how wide each cell needs to be
    cell_widths = {}
    for c in columns:
        lens = []
        values = [lens.append(len(str(d.get(c, "")))) for d in data]
        lens.append(len(c))
        lens.sort()
        cell_widths[c] = max(lens)

    # Used for formatting rows of data
    row_template = "|" + " {} |" * len(columns)

    # CONSTRUCT THE TABLE

    # The top row with the column titles
    justified_column_heads = [c.ljust(cell_widths[c]) for c in columns]
    header = row_template.format(*justified_column_heads)
    # The second row contains separators
    sep = "|" + "-" * (len(header) - 2) + "|"
    end = "-" * len(header)
    # Rows of data
    rows = []

    for d in data:
        fields = [str(d.get(c, "")).ljust(cell_widths[c]) for c in columns]
        row = row_template.format(*fields)
        rows.append(row)
    rows.append(end)
    return "\n".join([header, sep] + rows)

Usage Example

cols = ["daynumber", "day", "weather"]
data = [
    {"day": "Sunday", "daynumber": 0, "weather": "poor", "year": 2016},
    {"day": "Monday", "daynumber": 1, "weather": "worse", "year": 2016},
    {"day": "Tuesday", "daynumber": 2, "weather": "better", "year": 2016},
    {"day": "Wednesday", "daynumber": 3, "weather": "overcast", "year": 2016},
    {"day": "Thursday", "daynumber": 4, "weather": "depressing", "year": 2016},
    {"day": "Friday", "daynumber": 5, "weather": "stay inside", "year": 2016},
    {"day": "Saturday", "daynumber": 6, "weather": "poor", "year": 2016}
]

print make_table(cols,data)