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.97Expressions 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: adultYou 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} = 42Multiline 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: 30Alternatively, 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.1416Thousands Separator
Use , to add a thousands separator:
population = 1_234_567
print(f"{population:,}")1,234,567Percentage
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+08Alignment 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): FFDebugging 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)=3The = 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 .
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page