An f-string evaluates the expression inside the braces and drops the result into the string. It is faster than % and .format(), and it reads in the order you think.
The part after the colon is a format specification, and that is where most of the useful behaviour lives.
The basics
The f before the quote is what makes the braces active.
# the basics
name, age = 'ada', 36
print(f'{name} is {age}')
It prints:
ada is 36
Any expression fits inside
Method calls, indexing, arithmetic and comparisons all work.
# any expression fits inside the braces
items = ['a', 'b', 'c']
print(f'{len(items)} items, first is {items[0].upper()}')
print(f'{age * 2} and {age > 30}')
It prints:
3 items, first is A
72 and True
Keep them short. If the expression needs thought, name it on the line above.
Number formatting
After the colon: fill and alignment, then width, then precision and type.
# number formatting
price = 1234.5678
print(f'{price:.2f}')
print(f'{price:,.2f}')
print(f'{price:>12.2f}|')
print(f'{price:<12.2f}|')
print(f'{price:^12.2f}|')
print(f'{0.4567:.1%}')
It prints:
1234.57
1,234.57
1234.57|
1234.57 |
1234.57 |
45.7%
< is left, > is right, ^ is centre. The comma inserts thousands separators, and % multiplies by 100 and adds the sign.
Lining up columns
Width plus alignment is enough for readable console tables.
# padding and alignment for tables
rows = [('apple', 3), ('bread', 12), ('milk', 1)]
for item, qty in rows:
print(f'{item:<10}{qty:>4}')
It prints:
apple 3
bread 12
milk 1
The equals sign for debugging
Putting = at the end prints the expression as well as its value. This is the fastest print debugging in Python.
# the = suffix prints the expression too
total = sum(q for _, q in rows)
print(f'{total=}')
print(f'{len(rows)=}')
It prints:
total=16
len(rows)=3
Dates and other types
The format spec is passed to the object, so anything with a __format__ method has its own mini language. Dates use strftime codes.
# dates and other __format__ types
import datetime
when = datetime.datetime(2026, 8, 20, 14, 30)
print(f'{when:%d %B %Y}')
print(f'{when:%H:%M}')
It prints:
20 August 2026
14:30
Literal braces
Double them.
# literal braces are doubled
print(f'{{not a placeholder}} but {name} is')
It prints:
{not a placeholder} but ada is
Zero padding, signs and fill characters
A zero before the width pads with zeros. A plus forces the sign to be shown. Any character before the alignment marker becomes the fill.
# fill characters and signs
print(f'{42:05d}')
print(f'{42:+d} {-42:+d}')
print(f'{"title":*^20}')
It prints:
00042
+42 -42
*******title********
What to remember
- The format spec goes after a colon inside the braces.
:,.2fcovers most money formatting.f"{value=}"prints the expression and the value.- Double the braces when you want a literal brace.
One warning: never build SQL or shell commands with f-strings. Use the parameter support in your database driver, and subprocess with a list.