⇦ Back

Strings 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>)

1 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

2 Strings

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   |

3 Number Types

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 shown
  • 16f omits a number of decimal places and just specifies a width (including decimal point) of 16 characters
  • f on its own does not specify a width or decimal place requirement
print('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%|

4 Additional Number Formatting

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

5 Alignment

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        |

6 Long Lines

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.

⇦ Back