format()
method¶format()
methodThe most basic way to print something in python is simply to use the print
command, followed by the string to print:
print "King Arthur"
The print
command also accepts variable names:
castle = "Camelot"
print castle
Strings and variables can be mixed by using a comma to separate them:
print "King Arthur lived in", castle
Note¶
A space is automatically added between the different arguments.
Using the print
command is easy and works very well for simple cases, but it has no formatting options, and sometimes you may need more flexibility.
There are numerous situations when it is useful to print an object in a specific output format.
When dealing with floating-point numbers, it is common to want to limit the output shown to a few decimals.
As an example, let's use $\pi$ and $e$, two constants defined in the math
module:
import math
print math.pi
print math.e
Our goal is to print "pi is" followed by the actual value of $\pi$ rounded to 2 decimals. Let's start by printing the string we need:
print "pi is ..."
In python, every string has a format()
method. Let's apply that method to our string:
print "pi is ...".format()
When format()
is applied to a string but given no arguments, the output string is not modified.
However, we now have the structure needed to print any object anywhere in the string.
To print the value of $\pi$ in the string, we must do 2 things:
specify in the string where we want to put our variable, which we do by adding curly braces with a zero inside
specify in the format()
method which object should be printed, which we do by adding math.pi
as argument to format()
print "pi is {0}".format(math.pi)
In the string, the curly braces with a 0 inside ({0}
) are replaced by the first argument in the format()
method. (Recall that in python, the index starts at 0.)
If we add a second argument in the format()
method, we can refer to both of those in the string:
print "pi is {0} and e is {1}".format(math.pi, math.e)
The curly braces with 0 ({0}
) refer to the first argument, the curly braces with 1 ({1}
) refer to the second argument, etc.
Instead of using the index of the arguments, we can name them to make things even more clear:
print "pi is {pi} and e is {e}".format(pi=math.pi, e=math.e)
The curly braces with pi
({pi}
) refer to the argument named pi
in the format()
method, and the curly braces with e
({e}
) refer to the argument named e
.
The default output of the format()
method is exactly the same as the output of the print
command. However, the format()
method allows us to decide precisely how the objects should be printed. To add a specification, the identifier must be followed by a column and the specification requested:
print "pi is {pi:.2f} and e is {e:.3f}".format(pi=math.pi, e=math.e)
In the example above:
f
), with 2 decimals (indicated by .2
)f
) with 3 decimals (.3
)Note¶
The specification depends on the type of objects to be printed: for instance, limiting the number of decimals would have no meaning for a string.
However, the specification always follows the same model:{identifier:specification}
Here is another example involving a large number:
print "large is {number}".format(number=math.pi*1E6)
The default output shows all the digits, but it is possible to use the exponential notation instead:
print "large is {number:.2e}".format(number=math.pi*1E6)
In the example above, the number is shown with the exponential notation (indicated by the e
) and with 2 decimals (indicated by the .2
).
A useful specifier is g
, which does automatic formatting of numbers:
print "pi is {pi:g}".format(pi=math.pi)
Another useful specifier is %
, which shows percentages:
students = 24
success = 20
print "The success rate is {rate:.1%}".format(rate=float(success)/students)
In the example above, the number is shown as a percentage (indicated by the %
) and with 1 decimal (indicated by the .1
).
Note¶
Formatting output is often used in two different situations:
- to show the output to a human; or
- to save the output in a file.
Those two situations require slightly different formatting specifications:
- To format output for a human, it is best to be totally explicit about the desired layout (number of decimals, field width, etc).
- To format output that it is machine-readable, it is best to use a different separator (typically, a tab), although the visual alignment may not be perfect.
The Hubble constant gives an estimated value of the rate of expansion of the Universe.
Below are a few recent measurements of the Hubble constant (restricted to those that have symmetric errors).
The goal is to output the different values into a machine-readable table.
Therefore, each field should be separated by a tab (use "\t" to insert a tab).
The columns should be in the following order: mission, measurement, error.
The numbers should all be shown with one decimal.
Because of the tabs, the visual alignment of the columns will not be perfect; another challenge below will correct that.
missions = ["Planck", "WMAP (9 years)", "WMAP (7 years)", "Hubble"]
measurements = [67.80, 69.32, 71.0, 71]
errors = [0.77, 0.80, 2.5, 8]
Source: Wikipedia
If you use $\LaTeX$, change the output so that the measurement and the error are combined together and ready to be included in a $\LaTeX$ document ($measurement \pm error$
), and leave all available digits.
The curly braces are used to indicate a replacement field, thus they do not appear in the output. If you do want to show curly braces, simply double them:
print "LaTeX makes heavy use of the {{ and }} symbols".format()
The errors on measurements can also be asymmetric.
Similarly to the previous challenges, below are a few other recent measurements of the Hubble constant, but this time restricted to those that have asymmetric errors.
If you use $\LaTeX$, create an output suitable for inclusion into a $\LaTeX$ document, by printing the name of the mission, followed by a tab, and then by the result of the experiment as $measurement^{+error_up}_{-error_down}$
missions = ["WMAP7", "WMAP5", "Chandra"]
measurements = [70.4, 71.9, 77.6]
up_errors = [1.3, 2.6, 14.9]
down_errors = [1.4, 2.7, 12.5]
Source: Wikipedia
Let's look at how to format text using a poem as an example:
author = "Robert Herrick"
life = "1591-1674"
title = "To the Virgins, to Make Much of Time"
poem = '''Gather ye rosebuds while ye may,
Old time is still a-flying;
And this same flower that smiles today
Tomorrow will be dying.
The glorious lamp of heaven the sun,
The higher he's a-getting,
The sooner will his race be run,
And nearer he's to setting.
That age is best which is the first,
When youth and blood are warmer;
But being spent, the worse, and worst
Times still succeed the former.
Then be not coy, but use your time,
And, while ye may, go marry;
For, having lost but once your prime,
You may forever tarry.'''
Source: Wikipedia
Let's start by printing a little bit of text, for instance the author name, surrounded by two asterisks:
print "*{text}*".format(text=author)
We have added asterisks on both sides to that we see the width of the field. By default, the field width is as large as the content (but not larger).
We can specify the width of the field explicitly:
print "*{text:50}*".format(text=author)
In the example above, the field width is set to be (at least) 50 characters.
Note¶
If the specified field width is smaller than the content, the field width will simply be ignored and the complete content will be shown.
For instance,print "*{text:3}*".format(text=author)
prints the complete author name, even though the output has more than 3 characters.
The default justification for strings is to the left, but it can be changed:
print "*{text:<50}*".format(text=author)
print "*{text:^50}*".format(text=author)
print "*{text:>50}*".format(text=author)
In the examples above, the string is justified to the left (indicated by <
), center (^
), and right (>
).
When the field width is larger than the content, we can specify the characted used to fill the empty spaces:
print "*{text:-^50}*".format(text=author)
In the example above, the string is justified to the center (indicated by ^
), and the fill character is a dash (indicated by -
).
Let's print each line of the poem, and the length of each line:
for line in poem.split('\n'):
print "{length} {line}".format(length=len(line), line=line)
This shows that the longest line has 38 characters. To output the poem, we can thus specify any field width larger than 38.
Therefore, if we use a field width of 78 characters surrounded by an asterisk on both sides, each line will have 80 characters in total.
Note¶
Historically, shells were often restricted to 80 characters in width.
Although that technical limitation does not apply to modern shells anymore, it is still customary to limit lines to be 80 characters at most.
As a final example, let's format the entire poem:
print "{title}".format(title=title)
print "*"*80
for line in poem.split('\n'):
# print line
print "*{line:^78}*".format(line=line)
print "*"*80
print "{author:>80}".format(author=author)
print "{life:>80}".format(life=life)
In a previous challenge, you output a machine-readable table with measurements of the Hubble constant with symmetric errors.
In this challenge, the goal is to output the different values into a table that looks nice to a human.
Therefore, the tabs between the columns should be removed, and the mission column should be set to be 20 characters wide.
As before, the numbers should all be shown with one decimal, and the columns should be in the following order: mission, measurement, error.
missions = ["Planck", "WMAP (9 years)", "WMAP (7 years)", "Hubble"]
measurements = [67.80, 69.32, 71.0, 71]
errors = [0.77, 0.80, 2.5, 8]
Source: Wikipedia
The format specification mini-language is part of the python documentation for strings; it describes all the available options (and there are many more than those described here!) and gives plenty of examples.
The python documentation for strings, also contains an introduction to the use of the format()
method as well as numerous examples.
More details about the format()
method are available in the Python Enhancement Proposal (PEP) 3101, entitled "Advanced String Formatting"
format()
methodformat()
method# Argument referred to by index:
print "King Arthur lived in {0}".format("Camelot")`
# Argument referred to by name (preferred, as it leads to clearer code):
print "King Arthur lived in {castle}".format(castle="Camelot")
print "pi is {pi:.2f}".format(pi=math.pi)
print "*{king:^50}*".format(king="King Arthur")