How to Use f-strings in Python
Python 3.6 introduced a new feature, known as formatted string literals, or f-strings, to simplify the use of the string method format()
.
- Lexical analysis - Formatted string literals — Python 3.11.3 documentation
- PEP 498 -- Literal String Interpolation | Python.org
For a detailed overview of the string method format()
, the built-in function format()
, and format specification strings, refer to the following article.
Basic usage of f-strings
The format()
method inserts values into the replacement field {}
using positional or keyword arguments.
a = 123
b = 'abc'
print('{} and {}'.format(a, b))
# 123 and abc
print('{first} and {second}'.format(first=a, second=b))
# 123 and abc
An f-string is a string literal prefixed with f
or F
, like f'...'
or F'...'
. It allows you to specify variables directly in the replacement field {}
.
print(f'{a} and {b}')
# 123 and abc
print(F'{a} and {b}')
# 123 and abc
Like regular string literals, f-strings can use single quotes ''
, double quotes ""
, and triple quotes '''
, """
.
print(f"{a} and {b}")
# 123 and abc
print(f'''{a} and {b}''')
# 123 and abc
print(f"""{a} and {b}""")
# 123 and abc
Format specifications
As with the format()
method, f-strings can specify a variety of formats by adding a format specification string after the colon :
in {}
.
Some examples are shown here. For more information, refer to the following article.
Left-justify, center, right-justify
s = 'abc'
print(f'right : {s:*>8}')
print(f'center: {s:*^8}')
print(f'left : {s:*<8}')
# right : *****abc
# center: **abc***
# left : abc*****
Zero-padding
i = 1234
print(f'zero padding: {i:08}')
# zero padding: 00001234
Separator
i = 1234567890
print(f'comma: {i:,}')
# comma: 1,234,567,890
Binary, octal, and hexadecimal representation
i = 255
print(f'bin : {i:b}')
print(f'oct : {i:o}')
print(f'hex(lower): {i:x}')
print(f'hex(upper): {i:X}')
# bin : 11111111
# oct : 377
# hex(lower): ff
# hex(upper): FF
print(f'bin : {i:08b}')
print(f'oct : {i:08o}')
print(f'hex(lower): {i:08x}')
print(f'hex(upper): {i:08X}')
# bin : 11111111
# oct : 00000377
# hex(lower): 000000ff
# hex(upper): 000000FF
print(f'bin : {i:#010b}')
print(f'oct : {i:#010o}')
print(f'hex(lower): {i:#010x}')
print(f'hex(upper): {i:#010X}')
# bin : 0b11111111
# oct : 0o00000377
# hex(lower): 0x000000ff
# hex(upper): 0X000000FF
Decimal places and significant digits
f = 12.3456
print(f'decimal places : {f:.3f}')
print(f'significant digits: {f:.3g}')
# decimal places : 12.346
# significant digits: 12.3
Scientific notation
f = 12.3456
print(f'exponent(lower): {f:.3e}')
print(f'exponent(upper): {f:.3E}')
# exponent(lower): 1.235e+01
# exponent(upper): 1.235E+01
Percentage
f = 0.123
print(f'percent: {f:.2%}')
# percent: 12.30%
Date and time (datetime
)
import datetime
dt = datetime.datetime(2020, 1, 5, 20, 15, 30)
print(f'datetime: {dt}')
# datetime: 2020-01-05 20:15:30
print(f'datetime: {dt:%A, %m/%d/%Y %I:%M:%S %p}')
# datetime: Sunday, 01/05/2020 08:15:30 PM
print(f'datetime: {dt.isoformat()}')
# datetime: 2020-01-05T20:15:30
For more information on the datetime
module, see the following article.
As in the last example, it is easier to use the isoformat()
method than to specify format codes when converting to ISO 8601 format.
Braces (curly brackets) {}
To include braces {
and }
in f-strings, double them like {{
and }}
. Note that the backslash \
cannot be used.
n = 123
print(f'{{}}-{n}-{{{n}}}')
# {}-123-{123}
Nested replacement fields
Similar to the format()
method, f-strings allow replacement fields within other replacement fields. The number in the format specification string can be a variable.
n = 123
i = 8
print('{n:0{i}}'.format(n=n, i=i))
# 00000123
print(f'{n:0{i}}')
# 00000123
You could also write:
f = 1.2345
for i in range(5):
print(f'{f:.{i}f}')
# 1
# 1.2
# 1.23
# 1.234
# 1.2345
Raw strings and f-strings
In regular strings, backslash \
represents special characters. However, when a string is prefixed with r
or R
, creating a raw string literal, backslash escapes are disregarded.
print('x\ty')
# x y
print(r'x\ty')
# x\ty
If you prefix a string with both r
and f
, it will be treated as both a raw string and an f-string. The order of r
and f
doesn't matter, and you can use either lowercase or uppercase letters.
x = 'XXX'
y = 'YYY'
print(f'{x}\t{y}')
# XXX YYY
print(rf'{x}\t{y}')
# XXX\tYYY
print(FR'{x}\t{y}')
# XXX\tYYY
Difference between the format()
method and f-strings
Expressions
With the format()
method, expressions cannot be included in the replacement field.
a = 3
b = 4
# print('{a} + {b} = {a + b}'.format(a=a, b=b))
# KeyError: 'a + b'
In contrast, f-strings allow the use of expressions within the replacement field. It is also possible to specify a format specification string for the outcome of the expression.
print(f'{a} + {b} = {a + b}')
# 3 + 4 = 7
print(f'{a} * {b} = {a * b}')
# 3 * 4 = 12
print(f'{a} / {b} = {a / b:.2e}')
# 3 / 4 = 7.50e-01
How to specify dictionary keys
When using a dictionary (dict
) in a replacement field, the format()
method does not require the key to be surrounded by '
or "
.
d = {'key1': 10, 'key2': 20}
print('{0[key1]}, {0[key2]}'.format(d))
# 10, 20
# print('{0["key1"]}, {0["key2"]}'.format(d))
# KeyError: '"key1"'
However, f-strings require the key to be enclosed in '
or "
.
print(f'{d["key1"]}, {d["key2"]}')
# 10, 20
# print(f'{d[key1]}, {d[key2]}')
# NameError: name 'key1' is not defined
Like regular strings, you cannot use the same quotation marks within the string as the ones enclosing the entire string. For example, if the whole string is enclosed in "
, use '
inside.
# print(f'{d['key1']}, {d['key2']}')
# SyntaxError: invalid syntax
print(f"{d['key1']}, {d['key2']}")
# 10, 20
Note that backslash escaping cannot be used within a replacement field.
# print(f'{d[\'key1\']}, {d[\'key2\']}')
# SyntaxError: f-string expression part cannot include a backslash
The =
specifier in f-strings (Python 3.8 and later)
From Python 3.8, f-strings support an =
specifier, which prints both variable names and their corresponding values.
i = 123
print(f'{i=}')
# i=123
If you place a space before or after the variable name and =
, it will be preserved in the output.
print(f'{i = }')
# i = 123
print(f'{ i = }')
# i = 123
You can also specify format specification strings and expressions with the =
specifier.
print(f'{i = :#b}')
# i = 0b1111011
print(f'{i * 2 = }')
# i * 2 = 246
This also applies to lists and dictionaries.
l = [0, 10, 20]
print(f'{l = }, {l[1] = }')
# l = [0, 10, 20], l[1] = 10
d = {'key1': 10, 'key2': 20}
print(f'{d = }, {d["key1"] = }')
# d = {'key1': 10, 'key2': 20}, d["key1"] = 10