Format Strings and Numbers in Python: format()
In Python, you can convert numbers and strings to various formats with the built-in function format()
or the string method str.format()
.
Note that f-strings were introduced in Python 3.6 as a more concise way of using str.format()
. Please refer to the following article for more information.
The built-in function: format()
Python provides the built-in format()
function for formatting strings.
This function takes the original string (str
) and number (int
or float
) to be formatted as its first argument, and the format specification string as its second argument. The function then returns the formatted string.
i = 255
print(format(i, '#04x'))
print(type(format(i, '#04x')))
# 0xff
# <class 'str'>
s = 'abc'
print(format(s, '*^10'))
# ***abc****
Details of the format specification string are described later.
The string method: str.format()
The format()
method is available on strings (str
).
In the string that calls the format()
method, the {}
is known as the replacement field, which is substituted with the format()
method's argument. The format specification can be written after :
in {}
.
Here is the equivalent code using the format()
method, corresponding to the above example with the built-in format()
function.
print('{:#04x}'.format(i))
print(type('{:#04x}'.format(i)))
# 0xff
# <class 'str'>
print('{:*^10}'.format(s))
# ***abc****
Specify arguments for the replacement field {}
Positional arguments
A string may contain multiple replacement fields. By default, the arguments of format()
are inserted in the order they are given.
print('{}-{}-{}'.format(255, 'abc', 1.23))
# 255-abc-1.23
If the number of {}
is small, the extra arguments are ignored; if the number of {}
is large (not enough arguments), an error will be raised.
print('{}-{}'.format(255, 'abc', 1.23))
# 255-abc
# print('{}-{}-{}-{}'.format(255, 'abc', 1.23))
# IndexError: Replacement index 3 out of range for positional args tuple
The numeric index
You can specify the numeric index in {}
, like {0}
or {1}
. They are replaced by the corresponding arguments.
The same number can be used more than once.
print('{0}-{1}-{0}'.format(255, 'abc'))
# 255-abc-255
Keyword arguments
You can also specify any name within {}
and provide it as a keyword argument to format()
.
print('{name} is {age} years old.'.format(name='Alice', age=20))
# Alice is 20 years old.
Specify list or dictionary
You can also use lists and dictionaries as arguments to format()
.
To specify the index of the list or the key of the dictionary in the replacement field, use []
. Make sure not to use '
or "
when specifying dictionary keys.
l = ['one', 'two', 'three']
print('{0[0]}-{0[1]}-{0[2]}'.format(l))
# one-two-three
d1 = {'name': 'Alice', 'age': 20}
d2 = {'name': 'Bob', 'age': 30}
print('{0[name]} is {0[age]} years old.\n{1[name]} is {1[age]} years old.'.format(d1, d2))
# Alice is 20 years old.
# Bob is 30 years old.
A list can be expanded into positional arguments using *
, and a dictionary into keyword arguments using **
.
l = ['one', 'two', 'three']
print('{}-{}-{}'.format(*l))
# one-two-three
d = {'name': 'Alice', 'age': 20}
print('{name} is {age} years old.'.format(**d))
# Alice is 20 years old.
Braces (curly brackets) {}
If you want to include braces {
and }
in a string that calls format()
, use double braces like {{
and }}
. Note that the backslash \
cannot be used for this purpose.
print('{{}}-{num}-{{{num}}}'.format(num=100))
# {}-100-{100}
Format specifications
To specify the format, write the format specification string within {}
, separated by a colon :
. Details of format specifications are described next.
print('{num} = {num:#x} = {num:#b}'.format(num=255))
# 255 = 0xff = 0b11111111
Examples of format specification string in format()
Both the built-in format()
function and the str.format()
method use a format specification string to specify the desired format.
This section will illustrate some examples. The sample code uses the str.format()
method, but the same applies to the built-in format()
function.
Left-align, center, right-align: <
, ^
, >
, =
You can use <
, ^
, or >
to left-align, center, or right-align your text, respectively. Specify the total number of characters.
print('left : {:<10}'.format(100))
print('center: {:^10}'.format(100))
print('right : {:>10}'.format(100))
# left : 100
# center: 100
# right : 100
You can specify the padding character. If omitted, as in the example above, it is filled with spaces.
print('left : {:*<10}'.format(100))
print('center: {:*^10}'.format(100))
print('right : {:*>10}'.format(100))
# left : 100*******
# center: ***100****
# right : *******100
>
does not consider signs (-
, +
).
When =
is used instead of >
, the sign is placed first and then filled with the specified character. Details related to the sign are described below.
print('sign: {:0>10}'.format(-100))
print('sign: {:0=10}'.format(-100))
# sign: 000000-100
# sign: -000000100
While <
, ^
, and >
can be used with strings, an error is raised if =
is used. To apply =
to a string, you must first convert the string to a number with int()
or float()
.
# print('sign: {:0=10}'.format('-100'))
# ValueError: '=' alignment not allowed in string format specifier
print('sign: {:0=10}'.format(int('-100')))
# sign: -000000100
There are also ljust()
, center()
, and rjust()
methods provided. For more information, see the following article.
Zero-padding
By specifying 0
as the padding character and omitting the alignment option (<
, ^
, >
), it is treated as if =
is specified.
print('zero padding: {:0=10}'.format(100))
print('zero padding: {:010}'.format(100))
# zero padding: 0000000100
# zero padding: 0000000100
print('zero padding: {:0=10}'.format(-100))
print('zero padding: {:010}'.format(-100))
# zero padding: -000000100
# zero padding: -000000100
Since it is considered =
, an error is raised if a string is specified as an argument, as described above.
# print('zero padding: {:010}'.format('-100'))
# ValueError: '=' alignment not allowed in string format specifier
The zfill()
method is also provided for zero-padding. See the following article for more details.
Leading sign prefix: +
, space
By default, only negative numbers are prefixed with a sign -
.
However, by using +
in the format string, positive numbers are prefixed with +
. By using space in the format string, positive numbers are prefixed with a space.
print('sign: {}'.format(100))
print('sign: {}'.format(-100))
# sign: 100
# sign: -100
print('sign: {:+}'.format(100))
print('sign: {:+}'.format(-100))
# sign: +100
# sign: -100
print('sign: {: }'.format(100))
print('sign: {: }'.format(-100))
# sign: 100
# sign: -100
Note that, by default, the positive number is padded with an additional character when padding.
print('sign: {:06}'.format(100))
print('sign: {:06}'.format(-100))
# sign: 000100
# sign: -00100
print('sign: {:+06}'.format(100))
print('sign: {:+06}'.format(-100))
# sign: +00100
# sign: -00100
print('sign: {: 06}'.format(100))
print('sign: {: 06}'.format(-100))
# sign: 00100
# sign: -00100
The sign option should be written after the alignment option.
print('sign: {:*>6}'.format(100))
print('sign: {:*>6}'.format(-100))
# sign: ***100
# sign: **-100
print('sign: {:*>+6}'.format(100))
print('sign: {:*>+6}'.format(-100))
# sign: **+100
# sign: **-100
print('sign: {:*> 6}'.format(100))
print('sign: {:*> 6}'.format(-100))
# sign: ** 100
# sign: **-100
Separator: ,
, _
A comma ,
or an underscore _
can be used as a thousands separator. Note that the underscore option was added in Python 3.6.
print('{:,}'.format(100000000))
print('{:_}'.format(100000000))
# 100,000,000
# 100_000_000
For float
, only the integer part is separated.
print('{:,}'.format(1234.56789))
print('{:_}'.format(1234.56789))
# 1,234.56789
# 1_234.56789
Binary, octal, hexadecimal: b
, o
, x
, X
You can format integers to binary, octal, and hexadecimal representations.
b
: binaryo
: octalx
: hexadecimal (lowercase)X
: hexadecimal (uppercase)
print('bin: {:b}'.format(255))
print('oct: {:o}'.format(255))
print('hex: {:x}'.format(255))
print('HEX: {:X}'.format(255))
# bin: 11111111
# oct: 377
# hex: ff
# HEX: FF
It is possible to use zero-padding for alignment when dealing with binary or hexadecimal notation.
print('bin: {:08b}'.format(255))
print('oct: {:08o}'.format(255))
print('hex: {:08x}'.format(255))
print('HEX: {:08X}'.format(255))
# bin: 11111111
# oct: 00000377
# hex: 000000ff
# HEX: 000000FF
Prefixes like 0b
or 0x
can be added with #
. Be aware that these prefixes are also accounted for when using zero-padding.
print('bin: {:#b}'.format(255))
print('oct: {:#o}'.format(255))
print('hex: {:#x}'.format(255))
print('HEX: {:#X}'.format(255))
# bin: 0b11111111
# oct: 0o377
# hex: 0xff
# HEX: 0XFF
print('bin: {:#010b}'.format(255))
print('oct: {:#010o}'.format(255))
print('hex: {:#010x}'.format(255))
print('HEX: {:#010X}'.format(255))
# bin: 0b11111111
# oct: 0o00000377
# hex: 0x000000ff
# HEX: 0X000000FF
Only the underscore _
can be used as a separator in binary, octal, and hexadecimal representations. Underscores are inserted every 4 digits.
print('hex: {:08x}'.format(255))
print('hex: {:09_x}'.format(255))
print('hex: {:#011_x}'.format(255))
# hex: 000000ff
# hex: 0000_00ff
# hex: 0x0000_00ff
Only integers (int
) can be formatted to binary, octal, or hexadecimal. If you want to format a numeric string, use int()
to convert it to an integer.
# print('hex: {:08x}'.format('255'))
# ValueError: Unknown format code 'X' for object of type 'str'
print('hex: {:08x}'.format(int('255')))
# hex: 000000ff
For more information on binary, octal, and hexadecimal representation in Python, see the following article.
Fixed-point notation: f
, F
Automatic conversion of float
to str
can result in scientific notation depending on the value. If you use f
in your format specification string, it will ensure the conversion to fixed-point notation.
print('{}'.format(0.00001234))
print('{}'.format(12340000000000000.0))
print('{:f}'.format(0.00001234))
print('{:f}'.format(12340000000000000.0))
# 1.234e-05
# 1.234e+16
# 0.000012
# 12340000000000000.000000
If you prefer scientific notation consistently, use e
or E
as detailed below.
As demonstrated above, six decimal places are used by default. To specify the number of decimal places (precision), use .[number of digits]f
.
print('{:.2f}'.format(123.456))
print('{:.5f}'.format(123.456))
print('{:.3f}'.format(0.0001234))
# 123.46
# 123.45600
# 0.000
If the resulting value has fewer digits than the original, the value is rounded. Note that this rounding adheres to the rules of even-number rounding. For example, 0.5
is rounded down to 0
.
print('{:.0f}'.format(0.4))
print('{:.0f}'.format(0.5))
print('{:.0f}'.format(0.6))
# 0
# 0
# 1
You can use the quantize()
method of the standard library decimal
for standard rounding (rounding half up). See the following article.
Values that exceed the maximum possible value for a float
are automatically treated as infinity, inf
. If F
is used, the output will be in uppercase: INF
. In such cases, nan
is also uppercase: NAN
.
print('{:.5f}'.format(10e1000))
print('{:.5F}'.format(10e1000))
# inf
# INF
Scientific notation: e
, E
By specifying e
or E
in your format string, you ensure the value is always converted to scientific notation. If e
is specified, the output will also be lowercase e
; if E
is specified, the output will be uppercase E
.
print('{:e}'.format(0.0001234))
print('{:E}'.format(0.0001234))
# 1.234000e-04
# 1.234000E-04
As with f
and F
, you can specify the number of digits following the decimal point. The integer part is one digit, and the decimal point is followed by the specified number of digits.
print('{:.5e}'.format(0.0001234))
print('{:.2e}'.format(0.0001234))
# 1.23400e-04
# 1.23e-04
print('{:.5e}'.format(987.65))
print('{:.2e}'.format(987.65))
# 9.87650e+02
# 9.88e+02
Note that e
, E
, +
, and -
are also taken into account when aligning the output.
print('{:>12.5e}'.format(987.65))
print('{:012.2e}'.format(987.65))
# 9.87650e+02
# 00009.88e+02
General format: g
, G
g
means "general format" and automatically switches between fixed-point and scientific notation depending on the value.
print('{:g}'.format(0.0001234))
print('{:g}'.format(0.00001234))
# 0.0001234
# 1.234e-05
You can specify significant digits using .[number of digits]g
. Note that this does not specify the number of decimal places.
The output may be converted to scientific notation.
print('{:.2g}'.format(123.456))
print('{:.3g}'.format(123.456))
print('{:.8g}'.format(123.456))
print('{:.3g}'.format(0.0001234))
# 1.2e+02
# 123
# 123.456
# 0.000123
As shown above, trailing zeros after the decimal point are omitted by default. If you add #
, these zeros won't be omitted. This also adds a trailing decimal point to integers.
print('{:#.2g}'.format(123.456))
print('{:#.3g}'.format(123.456))
print('{:#.8g}'.format(123.456))
print('{:#.3g}'.format(0.0001234))
# 1.2e+02
# 123.
# 123.45600
# 0.000123
Omitting g
gives the same result in most cases, but not when dealing with integer output.
print('{:.2}'.format(123.456))
print('{:.3}'.format(123.456))
print('{:.8}'.format(123.456))
print('{:.3}'.format(0.0001234))
# 1.2e+02
# 1.23e+02
# 123.456
# 0.000123
print('{:#.2}'.format(123.456))
print('{:#.3}'.format(123.456))
print('{:#.8}'.format(123.456))
print('{:#.3}'.format(0.0001234))
# 1.2e+02
# 1.23e+02
# 123.45600
# 0.000123
If you compare the same value formatted with f
, e
, g
, and the default, the results will look like this:
print('{:.3f}'.format(123.456))
print('{:.3e}'.format(123.456))
print('{:.3g}'.format(123.456))
print('{:.3}'.format(123.456))
# 123.456
# 1.235e+02
# 123
# 1.23e+02
print('{:.8f}'.format(123.456))
print('{:.8e}'.format(123.456))
print('{:.8g}'.format(123.456))
print('{:.8}'.format(123.456))
# 123.45600000
# 1.23456000e+02
# 123.456
# 123.456
If you want to display a wide range of values with fixed width, use the exponential notation of e
or E
.
print('{:.4e}'.format(123.456))
print('{:.4e}'.format(0.000012345))
print('{:.4e}'.format(12))
# 1.2346e+02
# 1.2345e-05
# 1.2000e+01
Remember, using G
instead of g
capitalizes letters, as in E
, INF
, or NAN
.
print('{:.2g}'.format(123.456))
print('{:.2g}'.format(10e1000))
print('{:.2G}'.format(123.456))
print('{:.2G}'.format(10e1000))
# 1.2e+02
# inf
# 1.2E+02
# INF
Percentage: %
By specifying %
in your format string, the value is multiplied by 100 and expressed as a percentage. Like with f
, you can specify the number of decimal places. Six decimal places are used by default.
Left-justified, centered, right-justified, and zero-filled alignments are also available. The %
symbol is also counted as a character.
print('{:%}'.format(0.12345))
print('{:.2%}'.format(0.12345))
# 12.345000%
# 12.35%
print('{:%}'.format(10))
print('{:.2%}'.format(10))
# 1000.000000%
# 1000.00%
print('{:>10.2%}'.format(0.12345))
print('{:010.2%}'.format(0.12345))
# 12.35%
# 000012.35%
Date and time (datetime
)
You can also use the format codes for the datetime
, date
, and time
objects from the datetime
module in the format string.
import datetime
dt = datetime.datetime(2020, 1, 5, 20, 15, 30)
print('datetime: {}'.format(dt))
# datetime: 2020-01-05 20:15:30
print('datetime: {:%A, %m/%d/%Y %I:%M:%S %p}'.format(dt))
# datetime: Sunday, 01/05/2020 08:15:30 PM
print('datetime: {}'.format(dt.isoformat()))
# datetime: 2020-01-05T20:15:30
As shown in the final example, using the isoformat()
method can be more convenient when you want to convert to the ISO 8601 format than specifying individual format codes.