Python String Formatting & f-strings
Formatting turns values into neat, readable text: prices with two decimals, columns that line up, percentages, dates. f-strings are the modern way to do it, and the format codes you learn here also work with str.format().
- Put values into text with f-strings
- Control decimals, width and alignment
- Format numbers, percentages and dates
- Recognise format() and % formatting in older code
f-string basics
Put an f before the opening quote and write any expression inside { }.
name = "Asha"tests, passed = 40, 37 print(f"{name} ran {tests} tests")print(f"Pass rate: {passed / tests}")print(f"Upper: {name.upper()}, failed: {tests - passed}")Asha ran 40 tests Pass rate: 0.925 Upper: ASHA, failed: 3
Format specifiers
After the expression, a colon starts the format specifier: {value:spec}.
pi = 3.14159265print(f"{pi:.2f}") # 2 decimal placesprint(f"{pi:.4f}")print(f"{1234567.891:,.2f}") # thousands separatorprint(f"{0.8125:.1%}") # percentageprint(f"{42:05d}") # pad with zeros to width 5print(f"{255:x} {255:b}") # hex and binary3.14 3.1416 1,234,567.89 81.2% 00042 ff 11111111
| Spec | Meaning | Example | Result |
|---|---|---|---|
.2f | fixed-point, 2 decimals | f"{3.14159:.2f}" | 3.14 |
, | thousands separator | f"{1500000:,}" | 1,500,000 |
.1% | percentage, 1 decimal | f"{0.256:.1%}" | 25.6% |
05d | zero-pad to width 5 | f"{42:05d}" | 00042 |
>10 | right-align in 10 chars | f"{'hi':>10}" | hi |
<10 / ^10 | left / centre | f"{'hi':^10}" | hi |
e | scientific | f"{12345.678:.2e}" | 1.23e+04 |
Width and alignment
Fixed widths make columns line up. < aligns left, > right and ^ centre; the character before the arrow is the fill.
rows = [("Keyboard", 2, 1499.5), ("Mouse", 10, 349), ("Monitor", 1, 12999)] print(f"{'Item':<10}{'Qty':>5}{'Price':>12}")print("-" * 27)for item, qty, price in rows: print(f"{item:<10}{qty:>5}{price:>12,.2f}")print(f"{' Total ':=^27}")Item Qty Price --------------------------- Keyboard 2 1,499.50 Mouse 10 349.00 Monitor 1 12,999.00 ========== Total ==========
Debugging with =
Adding = after the expression prints the expression and its value:
user_id = 7retries = 3print(f"{user_id=}, {retries * 2=}")user_id=7, retries * 2=6
Dates in f-strings
Date objects understand their own format codes (covered fully in the Datetime lesson):
from datetime import date d = date(2026, 11, 2)print(f"{d:%d %B %Y}")print(f"{d:%Y-%m-%d} is a {d:%A}")02 November 2026 2026-11-02 is a Monday
Braces and quotes inside f-strings
Double the braces to print them literally. Use a different quote style for strings inside the expression:
key = "id"print(f"{{{key}}}")data = {"id": 7}print(f"value: {data['id']}"){id}
value: 7str.format()
str.format() uses the same {} placeholders and format specs. You will see it in older code and when a template is stored in a variable:
template = "{name} scored {score:.1f}%"print(template.format(name="Ravi", score=87.456))print("{0} vs {1}, {0} wins".format("India", "Australia"))Ravi scored 87.5% India vs Australia, India wins
The old % style
The oldest style uses % codes. It still appears in logging calls and old scripts:
print("%s has %d items costing %.2f" % ("cart", 3, 499.999))cart has 3 items costing 500.00
Use f-strings for new code. They are the fastest and the easiest to read. Use str.format() only when the template must be defined before the values exist.
Check your understanding
Predict the output
x = 7.0 / 3print(f"[{x:.3f}] [{x:8.2f}] [{'ok':*^6}] [{1e6:,.0f}]")[2.333] [ 2.33] [**ok**] [1,000,000]
.3f keeps three decimals, 8.2f pads 2.33 to eight characters wide, ^6 centres “ok” in six characters using , and ,.0f adds separators with no decimals.
Quick quiz
1. Which prints 0.50 for x = 0.5?
.2f means fixed-point with 2 decimal places.
2. What does f"{0.25:.0%}" produce?
% multiplies by 100 and adds a percent sign.
3. How do you print a literal { in an f-string?
Doubled braces are printed as single braces.
Exercise: invoice line
Print each line as a 12-character left-aligned item name, the quantity right-aligned in 4 characters, and the line total with a thousands separator and 2 decimals in 12 characters.
[("Laptop", 2, 54999), ("USB cable", 5, 199.5)]Laptop 2 109,998.00 USB cable 5 997.50
Hint 1
The line total is qty * price; use the spec >12,.2f.
lines = [("Laptop", 2, 54999), ("USB cable", 5, 199.5)]for item, qty, price in lines: print(f"{item:<12}{qty:>4}{qty * price:>12,.2f}")Laptop 2 109,998.00 USB cable 5 997.50
Each {...} gets a width so the columns line up whatever the values are. The comma in the last spec adds the thousands separator.
Program Practice
106 Python String Programs
Every program has a step-by-step explanation, colour-coded code and its real output.
Python string formatting FAQ
How do I format a float to 2 decimal places in Python?
Use an f-string: f"{value:.2f}". It returns a string; use round(value, 2) if you need a number.
What is an f-string in Python?
An f-string is a string literal prefixed with f in which {expression} placeholders are replaced by their values. They were added in Python 3.6.
How do I add commas to large numbers in Python?
Use the , format option: f"{1234567:,}" gives 1,234,567.
Which is better: f-string, format() or %?
f-strings are the most readable and the fastest. str.format() is useful for reusable templates, and % formatting is mainly found in older code and logging.