f-Strings Formatting: Everything You Can Put Inside the Braces
- Prefix a string literal with
forFto enable f-string interpolation. - Curly braces
{}evaluate any Python expression at runtime. - A colon after the expression introduces a format spec:
{value:.2f}. - The
=specifier produces self-documenting debug output:{x=}printsx=42.
Basic syntax
An f-string is a string literal prefixed with f. Any expression inside {} is evaluated at runtime and its string representation is inserted:
name = "Ada"
age = 36
print(f"Name: {name}, Age: {age}")
# Name: Ada, Age: 36
F-strings replaced % formatting and .format() calls for most use cases because the expression lives right next to the surrounding text, making the connection obvious.
Arbitrary expressions inside braces
The expression slot accepts any valid Python expression, not just variable names:
items = [1, 2, 3, 4, 5]
print(f"Total: {sum(items)}, Average: {sum(items) / len(items):.1f}")
# Total: 15, Average: 3.0
import datetime
print(f"Year: {datetime.date.today().year}")
# Year: 2026
Avoid putting complex logic inside an f-string. If the expression requires more than one read to understand, compute the value first and assign it a descriptive variable name.
The format spec mini-language
After a colon, you can write a format specification that controls how the value is rendered. The colon itself is not part of the expression; everything after it is the spec:
pi = 3.14159265
print(f"{pi:.4f}") # 3.1416 (four decimal places)
print(f"{pi:10.3f}") # ' 3.142' (width 10, 3 decimals)
print(f"{pi:e}") # 3.141593e+00
Alignment and padding
| Spec | Meaning | Example | Output |
|---|---|---|---|
{v:10} | Pad to width 10, left-align strings | f"{'hi':10}|" | hi | |
{v:<10} | Left-align explicitly | f"{'hi':<10}|" | hi | |
{v:>10} | Right-align | f"{'hi':>10}|" | hi| |
{v:^10} | Centre | f"{'hi':^10}|" | hi | |
{v:*^10} | Centre, fill with * | f"{'hi':*^10}|" | ****hi****| |
Alignment is most useful when building fixed-width text tables for CLI output.
Number formatting
| Spec | Meaning | Example (n=1234567.89) |
|---|---|---|
:,.2f | Two decimals, thousands separator | 1,234,567.89 |
:.0f | No decimals (rounds) | 1234568 |
:+.1f | Always show sign | +1234567.9 |
:010.2f | Zero-pad to width 10 | 1234567.89 (already 10) |
:b | Binary | f"{42:b}" → 101010 |
:x | Hex lowercase | f"{255:x}" → ff |
:% | Percentage | f"{0.1752:.1%}" → 17.5% |
Debug output with the = specifier
Python 3.8 added the = specifier, which prints the expression text alongside its value. It is invaluable for quick debugging without a debugger:
x = 42
y = x * 2 + 1
print(f"{x=}, {y=}")
# x=42, y=85
items = [1, 2, 3]
print(f"{len(items)=}")
# len(items)=3
You can combine = with a format spec: f"{pi=:.4f}" prints pi=3.1416.
Multiline f-strings
Triple-quoted f-strings span multiple lines naturally. This is useful for building structured text output like reports or SQL queries:
user = {"name": "Bob", "plan": "pro", "seats": 5}
msg = f"""
Account summary
---------------
Name : {user['name']}
Plan : {user['plan'].upper()}
Seats : {user['seats']:>3}
"""
print(msg.strip())
subprocess argument lists instead. F-strings perform no escaping.