So, say you had a console Python application where you
are trying to print a table of numbers as your output. Printing the numbers
without any formatting is messy. By using formatting options for the
%
operator, you can make tables that are much easier to
read.
The first time you print a table, you might try the following:
print label, number_1, number_2, number_3
Your "table" would end up looking like:
The first row 1.001 2.0983 10.12
Another row 11.4 3.144 35.973
Look! Yet another row 12.6 99.72 1.892
Yikes, that table is ugly! I can't tell which number belongs to which
column. There must be a way to get Python to create a better looking table of
numbers. Good for us, there is. Batteries are included, after all. A quick
search yields a
reference on C-style string formatting in Python, but it is a bit light
in the examples department.
From the docs, it's pretty obvious that our code will be a string followed
by the % operator and then a tuple or dictionary. It even gives an example of
this where a string is printed with values from a dictionary. What it does
not tell us, is how we can use this to create our table.
The first thing we can do is make sure each column gets a specified amount
of characters. The longest string in our first column is 21 characters long,
so we'll want to make sure that when we make the table, all the rows end up
with a label taking up 21 characters. Likewise, the second column has a max
of 5 characters; the third has 6, and the last column also has a max of 6
characters. Also, to make the string formatting work, we have to realize that
the first column is a string, and the others are
floating-point values.
A simple example, just using the minimum width string formatting option
would look something like this:
row_dictionary = {
"label": label,
"1": number_1,
"2": number_2,
"3": number_3
}
print "%(label)21s %(1)5f %(2)6f %(3)6f" % row_dictionary
The first row 1.001000 2.098300 10.120000
Another row 11.400000 3.144000 35.973000
Look! Yet another row 12.600000 99.720000 1.892000
Already, that's looking a lot better! But wait, what happened to our
numbers? Why did they just get so much longer? The reason our floating-point
numbers got so much longer is because when formatting as %f there is a
default precision of 6. That means, all floating point numbers we give it
will end up having 6 digits after the decimal point--even if they wouldn't be
shown after running through str().
So, we have to decide how much precision we want our users to see. Since
the numbers I picked are rather arbitrary, the precisions I pick can be
arbitrary as well. I think a precision of 0 for the first, 1 for the second,
and 2 for the third will work well. If you are writing an actual program, you
can choose your precisions based on the user requirements. :-)
Our new example table using the precisions we decided will look something
like this:
print "%(label)21s %(1)3.0f %(2)6.1f %(3)6.2f" % row_dictionary
The first row 1 2.1 10.12
Another row 11 3.1 35.97
Look! Yet another row 13 99.7 1.89
I think we're almost done. Notice that by defining a precision less than
the amount of digits in the number, the final output is rounded accordingly.
Since most people expect string labels to be left aligned and because I want
to show how to use the "conversion flags", we'll make our label column
left-aligned instead of the default right alignment. That'll be pretty easy
to do, just put a - sign in front of the minimum width of 21.
print "%(label)-21s %(1)3.0f %(2)6.1f %(3)6.2f" % row_dictionary
The first row 1 2.1 10.12
Another row 11 3.1 35.97
Look! Yet another row 13 99.7 1.89
There you have it. A beautiful table created using Python's string
formatting operator. That's all there is to it. Now your data tables are that
much easier to read.