.format()
MethodStrings have a built-in formatting method which allows you to substitute values into them using replacement fields.
“Methods” are functions that can be performed on a particular object type using ‘dot notation’. In this case, string objects have the format method which can be called like this:
<str>.format(<arguments>)
Replacement fields are defined with curly brackets
placed inside of a string. These get replaced by the
arguments provided to the .format()
method
in the same order as they appear in the method call:
print('First argument: {}, second argument: {}'.format('one', 'two'))
## First argument: one, second argument: two
If the arguments are not strings, they get converted into strings when they get substituted in for the replacement fields:
print('First number: {}, second number: {}'.format(1, 2))
## First number: 1, second number: 2
Which argument gets substituted into which replacement field can be controlled by providing the positional indexes of the arguments:
print('Argument at index 0: {0}, argument at index 1: {1}'.format(111, 222))
## Argument at index 0: 111, argument at index 1: 222
print('Argument at index 1: {1}, argument at index 0: {0}'.format(111, 222))
## Argument at index 1: 222, argument at index 0: 111
The arguments can be keyword arguments in which case their keywords are used instead of their indexes:
print('I\'m a {profession} and I\'m {status}'.format(profession='lumberjack', status='okay'))
## I'm a lumberjack and I'm okay
A string argument can be explicitly designated as such by using the “s” format, with a colon separating the index and this format specifier:
print('Strings: {0:s} & {1:s}'.format('green eggs', 'ham'))
## Strings: green eggs & ham
If the indexes are omitted the colons need to stay:
print('Strings: {:s} & {:s}'.format('green eggs', 'ham'))
## Strings: green eggs & ham
An integer can be placed before the s
to specify the
width of the output (the number of characters worth of space taken up by
the output):
print('Strings with padding: |{:20s}|{:20s}|'.format('green eggs', 'blue eggs'))
## Strings with padding: |green eggs |blue eggs |
A second integer can be used before the s
(separated
from the width specifier by a decimal point) to specify the maximum
width of the string before it will be truncated. This can be used to
ensure there is always white space at the end of a string, even if it’s
long:
print('Strings with padding: | {:9.8s}| {:9.8s}|'.format('green eggs', 'blue eggs'))
## Strings with padding: | green eg | blue egg |
Numbers can’t be used together with the s
format, but
the str()
function can be called on a numeric argument to
convert it into a string . The !s
specifier does this in
the background:
print('Call str() on the argument: |{!s}|'.format(1))
## Call str() on the argument: |1|
print('Call str() on the argument, with padding: |{!s:6}|'.format(1))
## Call str() on the argument, with padding: |1 |
print('This works for Booleans too: |{!s:8}|{!s:8}|'.format(True, False))
## This works for Booleans too: |True |False |
Different types of numbers can be formatted differently. The formatting instruction goes after a colon while the index or keyword - if one is used - goes before the colon.
Decimal integers are formatted using a minimum width (number of characters of space that is taken up by the number) and the letter “d” after the colon:
print('d = decimal: |{:3d}|{:5d}|{:4d}|'.format(123456, 23, 123))
## d = decimal: |123456| 23| 123|
Fixed-point notation (“f”) is used for decimal
non-integers. The width of the output and the number of decimal places
shown (precision) can both be specified using
width.precision
as follows:
8.2f
indicates that the output (including decimal
point) will be 8 characters wide and that there will be 2 digits after
the decimal point.1f
omits the width specification and just indicates
that one decimal place will be shown16f
omits a number of decimal places and just specifies
a width (including decimal point) of 16 charactersf
on its own does not specify a width or decimal place
requirementprint('f = fixed-point: |{:f}|{:.1f}|{:8.2f}|'.format(123.123, 123.12, 123.12))
## f = fixed-point: |123.123000|123.1| 123.12|
Scientific notation is when exactly one digit
appears before the decimal point, the rest of the digits appear after it
and a power of ten is included. These numbers also have their format
specified using width.precision
and the
exponent (“e”) of the power of ten is included in the
width:
print('e = exponent: |{:e}|{:.1e}|{:8.2e}|'.format(123.123, 123.12, 123.12))
## e = exponent: |1.231230e+02|1.2e+02|1.23e+02|
Using the general format (“g”) allows Python to
choose either the f
or e
format, whichever it
thinks is better:
print('g = general: |{:g}|{:.1g}|{:8.2g}|'.format(123.123, 123.12, 123.12))
## g = general: |123.123|1e+02| 1.2e+02|
Numbers that represent percentages are multiplied by 100 and have a percent sign (%) appended:
print('% = percentage: |{:%}|{:.1%}|{:8.2%}|'.format(0.123, 0.234, 0.345))
## % = percentage: |12.300000%|23.4%| 34.50%|
White space around numbers that is being used to pad out a width specification can be filled with zeroes:
print('Padded zeroes: |{:05d}|{:07.3f}|'.format(11, 47.42))
## Padded zeroes: |00011|047.420|
When displaying a negative number, any white space around the number that is being used to pad out the width specification can be put after the minus sign:
print('Padding after minus sign: |{:=6d}|{:=6d}|'.format(4, -4))
## Padding after minus sign: | 4|- 4|
A sign can be shown for both positive and negative numbers:
print('Force sign: positive: {:+d}. negative: {:+d}'.format(4, -4))
## Force sign: positive: +4. negative: -4
Combining the above two examples, the white space can be put after the signs:
print('Padding after forced sign: |{:=+6d}|{:=+6d}|'.format(4, -4))
## Padding after forced sign: |+ 4|- 4|
A thousands separator can be used:
print('Thousands separator: {:,.2f}'.format(123456789.123))
## Thousands separator: 123,456,789.12
By default, strings get displayed on the left of the space that is specified by the width:
print('|{:20s}|{:20s}|'.format('Left', 'Left'))
## |Left |Left |
By default, numbers get displayed on the right of the space that is specified by the width:
print('|{:20.2f}|{:20.2}|'.format(8.125, 7.773))
## | 8.12| 7.8|
Alignment within a specified width can be forced to be left, right or
centered with the <
, >
and
^
characters:
print('|{:<20s}|{:<20.2f}|'.format('Left', 5.99))
## |Left |5.99 |
print('|{:>20s}|{:>20.2f}|'.format('Right', 5.99))
## | Right| 5.99|
print('|{:^20s}|{:^20.2f}|'.format('Centred', 5.99))
## | Centred | 5.99 |
There are various ways to handle long lines (that include line breaks) and which are being formatted.
Backslashes ‘escape’ the line breaks in your code so Python will treat it as if everything was on one line:
message = "Verdict: '{stars}' \
Review: '{review}' \
Reviewer: {name}".format(stars='★★★☆☆', review='Pretty good', name='Jack')
print(message)
## Verdict: '★★★☆☆' Review: 'Pretty good' Reviewer: Jack
The newline character \n
can be used to create a line
break:
print('First comment here: {}\nSecond comment here: {}'.format('One', 'Two'))
## First comment here: One
## Second comment here: Two
Line breaks in strings created with pairs of three quotation marks
("""
or '''
) will be treated as line breaks by
Python:
msg = """Lorem ipsum {} sit amet, consectetur adipiscing elit. Etiam in sem
dictum, lacinia nisi ac, {} lectus."""
print(msg.format('dolor', 'interdum'))
## Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam in sem
## dictum, lacinia nisi ac, interdum lectus.