Python f-strings: The Complete Guide to String Formatting
Learn Python f-strings with runnable examples: decimal places, thousands separators, percentages, alignment, escaping braces, new lines and more.
On this page
f-strings are the easiest way to put values into text in Python. They are short, fast and easy to read, and they can format numbers, line up columns and even help you debug. This guide covers everything people most often search for, with a runnable example for each.
What is an f-string?
An f-string is a normal string with the letter f in front of the opening quote. Anything inside curly braces is worked out and placed into the text.
name = "Ada"
age = 36
print(f"{name} is {age} years old")Ada is 36 years oldExpressions inside the braces
The braces can hold any Python expression, not just a variable name: sums, method calls, list indexing and function calls all work.
a, b = 6, 4
scores = [70, 85, 92]
print(f"{a} + {b} = {a + b}")
print(f"Shouted: {'hello'.upper()}")
print(f"Best score: {max(scores)}")6 + 4 = 10
Shouted: HELLO
Best score: 92Decimal places
Add a colon after the value, then a format specifier. .2f means "a decimal number with 2 digits after the point". It rounds for you.
price = 19.5
pi = 3.14159265
print(f"Price: {price:.2f}")
print(f"Pi to 3 places: {pi:.3f}")
print(f"No decimals: {pi:.0f}")Price: 19.50
Pi to 3 places: 3.142
No decimals: 3Thousands separators
A comma in the specifier adds thousands separators. You can combine it with decimal places, and an underscore works too.
population = 1234567
revenue = 9876543.219
print(f"{population:,}")
print(f"{revenue:,.2f}")
print(f"{population:_}")1,234,567
9,876,543.22
1_234_567Percentages
The % specifier multiplies by 100 and adds a percent sign. Put the number of decimal places in front of it.
passed = 0.256
print(f"Pass rate: {passed:.1%}")
print(f"Rounded: {passed:.0%}")Pass rate: 25.6%
Rounded: 26%Scientific notation
Use e for very large or very small numbers.
distance = 149600000000
tiny = 0.000042
print(f"{distance:.2e}")
print(f"{tiny:.1e}")1.50e+11
4.2e-05Padding and alignment
A number after the colon sets a minimum width. Use < to align left, > to align right and ^ to center. Put any character before the arrow to fill the space with it.
for fruit, price in [("apple", 1.2), ("kiwi", 0.5), ("mango", 2.75)]:
print(f"{fruit:<8}{price:>6.2f}")
print(f"{'menu':*^12}")apple 1.20
kiwi 0.50
mango 2.75
****menu****For numbers, a leading zero pads with zeros, which is handy for times and IDs:
hours, minutes = 7, 5
order = 42
print(f"{hours:02}:{minutes:02}")
print(f"Order #{order:05}")07:05
Order #00042How to print curly braces in an f-string
Because braces mean "put a value here", you escape a literal brace by doubling it: {{ prints { and }} prints }.
value = 42
print(f"Use {{name}} as a placeholder")
print(f"The set is {{{value}}}")Use {name} as a placeholder
The set is {42}In the second line, the outer pairs print literal braces and the middle {value} is replaced as usual.
New lines in f-strings
\n inside the text of an f-string starts a new line, exactly as in a normal string:
name = "Sam"
print(f"Hello, {name}!\nWelcome back.")Hello, Sam!
Welcome back.Putting a backslash *inside* the braces, for example to join a list with new lines, only works in Python 3.12 and later. PythonExecutor runs Python 3.12, so this works here:
items = ["eggs", "milk", "bread"]
print(f"Shopping list:\n{'\n'.join(items)}")Shopping list:
eggs
milk
breadOn older Python versions, store the newline in a variable first, such as newline = "\n", and use {newline.join(items)} instead.
Multi-line f-strings
For longer text, use triple quotes. Every line can contain braces.
name, total = "Mia", 3
receipt = f"""Customer: {name}
Items: {total}
Thank you!"""
print(receipt)Customer: Mia
Items: 3
Thank you!To split one long line in your code without adding new lines to the output, put several f-strings next to each other inside brackets. Python joins them:
user, points, level = "Kiran", 1250, 7
message = (
f"{user} has {points:,} points "
f"and is on level {level}."
)
print(message)Kiran has 1,250 points and is on level 7.Conditions inside an f-string
A one-line if/else (a conditional expression) works inside the braces:
for n in [3, 8]:
print(f"{n} is {'even' if n % 2 == 0 else 'odd'}")
count = 1
print(f"{count} item{'s' if count != 1 else ''}")3 is odd
8 is even
1 itemDates and times
Dates accept the same codes as strftime, right after the colon:
from datetime import date
day = date(2026, 10, 15)
print(f"{day:%d %B %Y}")
print(f"{day:%A}")15 October 2026
ThursdayDebugging with =
Add = after the expression and Python prints the expression as well as its value. It is a quick way to check variables.
score = 95
price = 19.5
print(f"{score=}")
print(f"{price * 2 = }")score=95
price * 2 = 39.0Quotes inside f-strings
If the text inside the braces needs quotes, the simplest choice is to use the other kind of quote from the one around the f-string:
user = {"name": "Ana"}
print(f"Hi {user['name']}")Hi AnaQuick reference
| You want | Write | Result |
|---|---|---|
| 2 decimal places | f"{3.14159:.2f}" | 3.14 |
| Thousands separators | f"{1234567:,}" | 1,234,567 |
| Percentage | f"{0.256:.1%}" | 25.6% |
| Scientific notation | f"{0.000042:.1e}" | 4.2e-05 |
| Zero padding | f"{7:03}" | 007 |
| Right align, width 6 | f"{42:>6}" | 42 with 4 spaces before it |
| Centered with stars | f"{'hi':*^6}" | **hi** |
| Literal braces | f"{{x}}" | {x} |
| Show name and value | f"{x=}" | x=5 |
Common mistakes
- Forgetting the f.
"Hello {name}"prints the braces literally. Thefgoes right before the opening quote. - Putting the format in the wrong place. The specifier goes after a colon inside the braces:
{price:.2f}, not{price}:.2f. - Using a format code on the wrong type.
.2fneeds a number. If the value came frominput(), convert it withfloat()first.
Try it yourself
Paste any example above into the PythonExecutor playground and press Run. Then change the numbers and the format codes to see what happens. Five minutes of experimenting is the fastest way to remember them.
By PythonExecutor Team