Standard Python string formatting may suffice.
# assume that your data rows are tuples
template = "{0:8}|{1:10}|{2:15}|{3:7}|{4:10}" # column widths: 8, 10, 15, 7, 10
print template.format("CLASSID", "DEPT", "COURSE NUMBER", "AREA", "TITLE") # header
for rec in your_data_source:
print template.format(*rec)
Or
# assume that your data rows are dicts
template = "{CLASSID:8}|{DEPT:10}|{C_NUM:15}|{AREA:7}|{TITLE:10}" # same, but named
print template.format( # header
CLASSID="CLASSID", DEPT="DEPT", C_NUM="COURSE NUMBER",
AREA="AREA", TITLE="TITLE"
)
for rec in your_data_source:
print template.format(**rec)
Play with alignment, padding, and exact format specifiers to get best results.
Answer from 9000 on Stack Overflow
» pip install tabulate
How to Print "Pretty" String Output in Python - Stack Overflow
How to get the columns to align perfectly on a table?
Python spacing and aligning strings - Stack Overflow
python - Printing Lists as Tabular Data - Stack Overflow
Standard Python string formatting may suffice.
# assume that your data rows are tuples
template = "{0:8}|{1:10}|{2:15}|{3:7}|{4:10}" # column widths: 8, 10, 15, 7, 10
print template.format("CLASSID", "DEPT", "COURSE NUMBER", "AREA", "TITLE") # header
for rec in your_data_source:
print template.format(*rec)
Or
# assume that your data rows are dicts
template = "{CLASSID:8}|{DEPT:10}|{C_NUM:15}|{AREA:7}|{TITLE:10}" # same, but named
print template.format( # header
CLASSID="CLASSID", DEPT="DEPT", C_NUM="COURSE NUMBER",
AREA="AREA", TITLE="TITLE"
)
for rec in your_data_source:
print template.format(**rec)
Play with alignment, padding, and exact format specifiers to get best results.
class TablePrinter(object):
"Print a list of dicts as a table"
def __init__(self, fmt, sep=' ', ul=None):
"""
@param fmt: list of tuple(heading, key, width)
heading: str, column label
key: dictionary key to value to print
width: int, column width in chars
@param sep: string, separation between columns
@param ul: string, character to underline column label, or None for no underlining
"""
super(TablePrinter,self).__init__()
self.fmt = str(sep).join('{lb}{0}:{1}{rb}'.format(key, width, lb='{', rb='}') for heading,key,width in fmt)
self.head = {key:heading for heading,key,width in fmt}
self.ul = {key:str(ul)*width for heading,key,width in fmt} if ul else None
self.width = {key:width for heading,key,width in fmt}
def row(self, data):
return self.fmt.format(**{ k:str(data.get(k,''))[:w] for k,w in self.width.iteritems() })
def __call__(self, dataList):
_r = self.row
res = [_r(data) for data in dataList]
res.insert(0, _r(self.head))
if self.ul:
res.insert(1, _r(self.ul))
return '\n'.join(res)
and in use:
data = [
{'classid':'foo', 'dept':'bar', 'coursenum':'foo', 'area':'bar', 'title':'foo'},
{'classid':'yoo', 'dept':'hat', 'coursenum':'yoo', 'area':'bar', 'title':'hat'},
{'classid':'yoo'*9, 'dept':'hat'*9, 'coursenum':'yoo'*9, 'area':'bar'*9, 'title':'hathat'*9}
]
fmt = [
('ClassID', 'classid', 11),
('Dept', 'dept', 8),
('Course Number', 'coursenum', 20),
('Area', 'area', 8),
('Title', 'title', 30)
]
print( TablePrinter(fmt, ul='=')(data) )
produces
ClassID Dept Course Number Area Title
=========== ======== ==================== ======== ==============================
foo bar foo bar foo
yoo hat yoo bar hat
yooyooyooyo hathatha yooyooyooyooyooyooyo barbarba hathathathathathathathathathat
I'm having a little trouble printing my lists onto a table, to where each column lines up with the very first row.
Below is my work so far;
Here are my lists:
first = ['Anna', 'Beatrice', 'Charles', 'David', 'Emma']
last = ['Anderson', 'Brown', 'Clark', 'Daniels', 'Edwards']
major = ['Mathematics', 'Data Science', 'Biology', 'Chemistry', 'Computer Science']
credits = [110, 83, 64, 35, 104]
gpa = [3.56, 3.24, 3.87, 2.83, 3.61]
_____________________________________________________________________________
and here is where I tried printing said list a la table mode:
print('First\tLast\tMajor\tCredits\tGPA')
print('-' * 56)
for i in range(0,4):
print(first[i], '\t', last[i], '\t', major[i], '\t', credits[i], '\t', gpa[i])
______________________________________________________________________________
I wish I can show the out put, but the copy paste won't work correctly. Basically what is happening is the top line where "First, Last, Major, etc) seems to be all squished together.
The elements of the lists are all messed up as well, including but not limited to some of the elements being in entirely incorrect columns.
If you can let me know if I may be overlooking anything, thank you!
You should be able to use the format method:
"Location: {0:20} Revision {1}".format(Location, Revision)
You will have to figure out the format length for each line depending on the length of the label. The User line will need a wider format width than the Location or District lines.
Try %*s and %-*s and prefix each string with the column width:
>>> print "Location: %-*s Revision: %s" % (20,"10-10-10-10","1")
Location: 10-10-10-10 Revision: 1
>>> print "District: %-*s Date: %s" % (20,"Tower","May 16, 2012")
District: Tower Date: May 16, 2012
There are some light and useful python packages for this purpose:
1. tabulate
https://pypi.python.org/pypi/tabulate
from tabulate import tabulate
print(tabulate([['Alice', 24], ['Bob', 19]], headers=['Name', 'Age']))
Name Age
------ -----
Alice 24
Bob 19
tabulate has many options to specify headers and table format.
print(tabulate(
[['Alice', 24], ['Bob', 19]],
headers=['Name', 'Age'],
tablefmt='orgtbl'))
| Name | Age |
|--------+-------|
| Alice | 24 |
| Bob | 19 |
2. PrettyTable
https://pypi.python.org/pypi/PrettyTable
from prettytable import PrettyTable
t = PrettyTable(['Name', 'Age'])
t.add_row(['Alice', 24])
t.add_row(['Bob', 19])
print(t)
+-------+-----+
| Name | Age |
+-------+-----+
| Alice | 24 |
| Bob | 19 |
+-------+-----+
PrettyTable has options to read data from csv, html, sql database. Also you are able to select subset of data, sort table and change table styles.
3. texttable
https://pypi.python.org/pypi/texttable
from texttable import Texttable
t = Texttable()
t.add_rows([['Name', 'Age'], ['Alice', 24], ['Bob', 19]])
print(t.draw())
+-------+-----+
| Name | Age |
+=======+=====+
| Alice | 24 |
+-------+-----+
| Bob | 19 |
+-------+-----+
with texttable you can control horizontal/vertical align, border style and data types.
4. termtables
https://github.com/nschloe/termtables
import termtables as tt
string = tt.to_string(
[["Alice", 24], ["Bob", 19]],
header=["Name", "Age"],
style=tt.styles.ascii_thin_double,
# alignment="ll",
# padding=(0, 1),
)
print(string)
+-------+-----+
| Name | Age |
+=======+=====+
| Alice | 24 |
+-------+-----+
| Bob | 19 |
+-------+-----+
with texttable you can control horizontal/vertical align, border style and data types.
Other options
- terminaltables - Easily draw tables in terminal/console applications from a list of lists of strings. Supports multi-line rows.
- asciitable can read and write a wide range of ASCII table formats via built-in Extension Reader Classes.
Some ad-hoc code:
row_format ="{:>15}" * (len(teams_list) + 1)
print(row_format.format("", *teams_list))
for team, row in zip(teams_list, data):
print(row_format.format(team, *row))
This relies on str.format() and the Format Specification Mini-Language.
I highly suggest you to convert your Table into a pandas Dataframe. If you do so, obtaining a tabular representation of your table is easy using to_markdown:
# Generating a test table in pandas
df = pd.DataFrame({'Column_2': {'test': 'Craig', 'test2': 'Bob', 'test3': 'Bill'},
'Column_3': {'test': False, 'test2': False, 'test3': False},
'Column_4': {'test': '[]', 'test2': '[]', 'test3': '[]'},
'Column_5': {'test': '<function Foo at 0x7f9f898a0e18>',
'test2': '<function Bar at 0x7f9f881ae730>',
'test3': '<function Baz at 0x7f9f881ae7b8>'}})
df.index.name = 'Column_1'
# Printing the table in a nice tabular way:
print(df.to_markdown())
| Column_1 | Column_2 | Column_3 | Column_4 | Column_5 |
|:-----------|:------------|:------------|:------------|:---------------------------------|
| test | Craig | False | [] | <function Foo at 0x7f9f898a0e18> |
| test2 | Bob | False | [] | <function Bar at 0x7f9f881ae730> |
| test3 | Bill | False | [] | <function Baz at 0x7f9f881ae7b8> |
In general, all table operations are supported by pandas, which is why it is not recommended to build your own Table structure (unless this is part of some learning course).
Use a well-known Python package to print in tabular format. For example, you may use prettytable. You can install it with the command: pip install prettytable.
>>> from prettytable import PrettyTable
>>> t = PrettyTable(hdrs)
>>>
>>> headers = ("Column_1", "Column_2", "Column_3", "Column_4", "Column_5")
>>> t = PrettyTable(headers)
>>> t.add_row(("test","Craig",False,[], 'Foo'))
>>> t.add_row(("test2","Bob",False,[], 'Bar'))
>>> t.add_row(("test3","Bill",False,[], 'Baz'))
>>> print(t)
+-----------+-----------+-----------+-----------+-----------+
| Column_1 | Column_2 | Column_3 | Column_4 | Column_5 |
+-----------+-----------+-----------+-----------+-----------+
| test | Craig | False | [] | Foo |
| test2 | Bob | False | [] | Bar |
| test3 | Bill | False | [] | Baz |
+-----------+-----------+-----------+-----------+-----------+
I want to construct a multiplication table and have the code below. however, when it prints out the code, the rows and columns aren't aligned correctly. How can I get them exactly aligned and in their right positions in the simplest way possible for me to grasp as a beginner?
rows= int(input("How many rows?: "))
columns= int(input("How many columns?: "))
for row in range(1, rows+1):
for col in range(1,columns+1):
print(row * col, end=" ")
print()I searched the internet and came across this video regarding the multiplication table in Python, but I'd want to have a second perspective.
Thank you very much!
Here is a simple, self-contained example that shows how to format variable column widths:
data = '''\
234 127 34 23 45567
23 12 4 4 45
23456 2 1 444 567'''
# Split input data by row and then on spaces
rows = [ line.strip().split(' ') for line in data.split('\n') ]
# Reorganize data by columns
cols = zip(*rows)
# Compute column widths by taking maximum length of values per column
col_widths = [ max(len(value) for value in col) for col in cols ]
# Create a suitable format string
format = ' '.join(['%%%ds' % width for width in col_widths ])
# Print each row using the computed format
for row in rows:
print format % tuple(row)
which outputs:
234 127 34 23 45567 23 12 4 4 45 23456 2 1 444 567
You need some way of finding the column size, maybe by reading all the data and finding the maximum width.
>>> line='234 127 34 23 45567'
>>> line.split()
['234', '127', '34', '23', '45567']
>>> max(map(len, line.split()))
5
Repeat over all lines, to find column size (e.g., 5).
Constructing a formatted line with percent formatting is straightforward.
>>> colsize = 5
>>> ' '.join(('%*s' % (colsize, i) for i in line.split()))
' 234 127 34 23 45567'
>>>
» pip install prettytable
One possible solution is to rely on some package that has been designed for this purpose, like tabulate: Read more about it!
Keep in mind that you have to install this using e.g. pip install tabulate
from tabulate import tabulate
print tabulate([[00, 00, 00], [00, 00, 00], [00, 00, 00]], headers=['X Coordinate','Y Coordinate','Result'], tablefmt='orgtbl')
Or use your original table with this code:
alignment = len(max(table.split("\t")))+1
for line in table.strip().split("\n"):
row ="{{:>{}}}".format(alignment) * len(line.strip().split("\t"))
print row.format(*line.strip().split("\t"))
This is a great resource for Python string formatting in general. Using the .format approach, you could use padding to align all of your strings with:
header = ['X Coordinate', 'Y Coordinate', 'Result']
row = ['00', '00', '00']
rows = [header, row, row, row]
print('\n'.join([''.join(['{:16}'.format(x) for x in r]) for r in rows]))
#X Coordinate Y Coordinate Result
#00 00 00
#00 00 00
#00 00 00
Or, using f-strings:
print('\n'.join([''.join([f'{x:16}' for x in r]) for r in rows]))
You can also right-align with (note the ':>16' in the format string):
print('\n'.join([''.join([f'{x:>16}' for x in r]) for r in rows]))
# X Coordinate Y Coordinate Result
# 00 00 00
# 00 00 00
# 00 00 00
So basically, put your data in to a list of lists and then decide on a desired row width and you can use the above single line to print things out nicely.