Python f-Strings: String Formatting in Python 3
f-strings, short for formatted string literals, are the most concise and readable way to format strings in Python. Introduced in Python 3.6, they let you embed variables and expressions directly inside a string by prefixing it with f or F.
This guide explains how to use f-strings in Python, including expressions, format specifiers, number formatting, alignment, and the debugging shorthand introduced in Python 3.8.
Basic Syntax
An f-string is a string literal prefixed with f. Any expression inside curly braces {} is evaluated at runtime and its result is inserted into the string:
name = "Leia"
age = 30
print(f"My name is {name} and I am {age} years old.")
My name is Leia and I am 30 years old.
Any valid Python expression can appear inside the braces — variables, attribute access, method calls, or arithmetic:
price = 49.99
quantity = 3
print(f"Total: {price * quantity}")
Total: 149.97
Expressions Inside f-Strings
You can call methods and functions directly inside the braces:
name = "alice"
print(f"Hello, {name.upper()}!")
Hello, ALICE!
Ternary expressions work as well:
age = 20
print(f"Status: {'adult' if age >= 18 else 'minor'}")
Status: adult
You can also access dictionary keys and list items:
user = {"name": "Bob", "city": "Berlin"}
print(f"{user['name']} lives in {user['city']}.")
Bob lives in Berlin.
Escaping Braces
To include a literal curly brace in an f-string, double it:
value = 42
print(f"{{value}} = {value}")
{value} = 42
Multiline f-Strings
To build a multiline f-string, wrap it in triple quotes:
name = "Leia"
age = 30
message = f"""
Name: {name}
Age: {age}
"""
print(message)
Name: Leia
Age: 30
Alternatively, use implicit string concatenation to keep each line short:
message = (
f"Name: {name}n"
f"Age: {age}"
)
Format Specifiers
f-strings support Python’s format specification mini-language. The full syntax is:
{value:[fill][align][sign][width][grouping][.precision][type]}
Floats and Precision
Control the number of decimal places with :.Nf:
pi = 3.14159265
print(f"{pi:.2f}")
print(f"{pi:.4f}")
3.14
3.1416
Thousands Separator
Use , to add a thousands separator:
population = 1_234_567
print(f"{population:,}")
1,234,567
Percentage
Use :.N% to format a value as a percentage:
score = 0.875
print(f"Score: {score:.1%}")
Score: 87.5%
Scientific Notation
Use :e for scientific notation:
distance = 149_600_000
print(f"{distance:e}")
1.496000e+08
Alignment and Padding
Use <, >, and ^ to align text within a fixed width. Optionally specify a fill character before the alignment symbol:
print(f"{'left':<10}|")
print(f"{'right':>10}|")
print(f"{'center':^10}|")
print(f"{'padded':*^10}|")
left |
right|
center |
**padded**|
Number Bases
Convert integers to binary, octal, or hexadecimal with the b, o, x, and X type codes:
n = 255
print(f"Binary: {n:b}")
print(f"Octal: {n:o}")
print(f"Hex (lower): {n:x}")
print(f"Hex (upper): {n:X}")
Binary: 11111111
Octal: 377
Hex (lower): ff
Hex (upper): FF
Debugging with =
Python 3.8 introduced the = shorthand, which prints both the expression and its value. This is useful for quick debugging:
x = 42
items = [1, 2, 3]
print(f"{x=}")
print(f"{len(items)=}")
x=42
len(items)=3
The = shorthand preserves the exact expression text, making it more informative than a plain print().
Quick Reference
| Syntax | Description |
|---|---|
f"{var}" |
Insert a variable |
f"{expr}" |
Insert any expression |
f"{val:.2f}" |
Float with 2 decimal places |
f"{val:,}" |
Integer with thousands separator |
f"{val:.1%}" |
Percentage with 1 decimal place |
f"{val:e}" |
Scientific notation |
f"{val:<10}" |
Left-align in 10 characters |
f"{val:>10}" |
Right-align in 10 characters |
f"{val:^10}" |
Center in 10 characters |
f"{val:*^10}" |
Center with * fill |
f"{val:b}" |
Binary |
f"{val:x}" |
Hexadecimal (lowercase) |
f"{val=}" |
Debug: print expression and value (3.8+) |
FAQ
What Python version do f-strings require?
f-strings were introduced in Python 3.6. If you are on Python 3.5 or earlier, use str.format() or % formatting instead.
What is the difference between f-strings and str.format()?
f-strings are evaluated at runtime and embed expressions inline. str.format() uses positional or keyword placeholders and is slightly more verbose. f-strings are generally faster and easier to read for straightforward formatting.
Can I use quotes inside an f-string expression?
Yes, but you must use a different quote type from the one wrapping the f-string. For example, if the f-string uses double quotes, use single quotes inside the braces: f"Hello, {user['name']}". In Python 3.12 and later, the same quote type can be reused inside the braces.
Can I use f-strings with multiline expressions?
Expressions inside {} cannot contain backslashes directly, but you can pre-compute the value in a variable first and reference that variable in the f-string.
Are f-strings faster than % formatting?
In many common cases, f-strings are faster than % formatting and str.format(), while also being easier to read. Exact performance depends on the expression and Python version, so readability is usually the more important reason to prefer them.
Conclusion
f-strings are the preferred way to format strings in Python 3.6 and later. They are concise, readable, and support the full format specification mini-language for controlling number precision, alignment, and type conversion. For related string operations, see Python String Replace
and How to Split a String in Python
.
