F-String Formatting in Python
F-string formatting means prefixing a string literal with f and putting variables or expressions in curly braces, so Python inserts their values when the line runs (Python 3.6+). A format spec after a colon controls the output: {now:%Y-%m-%d} for dates, {x:.2f} or {n:,} for numbers, and {s:>10} for alignment.
Quick answer: Write f"text {value:spec}", where the spec after the colon sets the format. Dates take strftime codes, as in f"{now:%Y-%m-%d %H:%M}". Numbers take .2f for two decimals, , for thousands separators and .1% for percentages. Alignment uses <, > or ^ plus a width, as in f"{name:>10}", and f"{n:05}" pads a number with leading zeros to a width of five.
How do you use an f-string in Python?
Prefix the string with f and put a variable name inside curly braces; Python replaces each placeholder with the variable's value. F-strings need Python 3.6 or later.
name = "Alice"
age = 30
# Old way
print("Hello, " + name + ". You are " + str(age))
# f-string way (Python 3.6+)
print(f"Hello, {name}. You are {age}")
# Output: Hello, Alice. You are 30
How do you format a date in an f-string?
Put strftime codes after the colon inside the braces: {now:%Y-%m-%d} prints a date such as 2024-03-15, %H:%M:%S prints a 24-hour time, and %B prints the full month name. This works for datetime, date and time objects because they pass the spec to strftime().
from datetime import datetime
now = datetime(2024, 3, 15, 14, 30, 45) # or datetime.now()
print(f"Date: {now:%Y-%m-%d}") # Output: Date: 2024-03-15
print(f"Time: {now:%H:%M:%S}") # Output: Time: 14:30:45
print(f"Full: {now:%B %d, %Y}") # Output: Full: March 15, 2024
Other codes you will reach for are %d/%m/%Y for day-first dates, %a and %b for abbreviated day and month names, and %I:%M %p for a 12-hour clock. Day and month names are in English unless you change the locale with locale.setlocale().
d = datetime(2024, 3, 5, 9, 7)
print(f"{d:%d/%m/%Y}") # Output: 05/03/2024
print(f"{d:%a %d %b %Y}") # Output: Tue 05 Mar 2024
print(f"{d:%I:%M %p}") # Output: 09:07 AM
print(f"{d:%A, %B} {d.day}") # Output: Tuesday, March 5
The last line uses {d.day} to drop the leading zero. The %-d code does the same on Linux and macOS, but Windows does not support it.
How do you format numbers in an f-string?
Add a format spec after a colon to control how a number displays: .2f for fixed decimals, , for thousands separators, % for percentages, and e for scientific notation. For more number cases, see Python f-string number formatting.
# Decimal places
pi = 3.14159265359
print(f"Pi: {pi:.2f}") # Output: Pi: 3.14
print(f"Pi: {pi:.4f}") # Output: Pi: 3.1416
# Comma separator for thousands
big_number = 1234567
print(f"Amount: {big_number:,}") # Output: Amount: 1,234,567
# Percentage
ratio = 0.857
print(f"Success rate: {ratio:.1%}") # Output: Success rate: 85.7%
# Scientific notation
tiny = 0.000001234
print(f"Value: {tiny:.2e}") # Output: Value: 1.23e-06
How do you align and pad values in an f-string?
Use < to left-align, > to right-align, and ^ to center a value within a set width. A 0 before the width pads numbers with leading zeros, and a character before the alignment sign sets a custom fill.
# Right align (10 characters wide)
print(f"{'right':>10}") # Output: right
# Left align
print(f"{'left':<10}") # Output: left
# Center
print(f"{'center':^10}") # Output: center
# Padding with zeros
number = 42
print(f"{number:05}") # Output: 00042
# Custom fill character
print(f"{'ab':*^9}") # Output: ***ab****
How do you combine alignment and number formatting?
Write the parts of the spec in a fixed order: fill and alignment, sign, width, thousands separator, precision, then type. So {price:>10,.2f} right-aligns in 10 characters with commas and two decimals, and a nested field such as {name:<{width}} takes the width from a variable.
rows = [("Coffee", 3.5), ("Sandwich", 8.25), ("Juice", 12)]
width = max(len(name) for name, _ in rows) # 8
for name, price in rows:
print(f"{name:<{width}} {price:>8,.2f}")
# Output:
# Coffee 3.50
# Sandwich 8.25
# Juice 12.00
Can you put expressions inside an f-string?
Yes, the braces hold any Python expression, not just variable names, so arithmetic, method calls and conditional expressions all work.
a = 5
b = 10
print(f"Sum: {a + b}, Product: {a * b}")
# Output: Sum: 15, Product: 50
# Method calls
name = "alice"
print(f"Uppercase: {name.upper()}")
# Output: Uppercase: ALICE
# Conditional expressions
score = 85
print(f"Result: {'Pass' if score >= 60 else 'Fail'}")
# Output: Result: Pass
Debugging with f-strings (Python 3.8+)
Add = after an expression and the f-string prints the expression text followed by its value, which is handy for quick debug output.
x = 10
y = 20
# The = operator shows variable name and value
print(f"{x=}, {y=}, {x+y=}")
# Output: x=10, y=20, x+y=30
Multiline F-Strings
Triple-quoted f-strings span multiple lines and accept the same placeholders and format specs as single-line f-strings.
name = "Alice"
items = 5
total = 99.99
message = f"""
Order Summary for {name}:
Items: {items}
Total: ${total:.2f}
"""
print(message)
What are the most common f-string formatting mistakes?
The usual f-string mistakes are a mistyped date code, braces meant to print literally, a number spec applied to a string, float rounding and reused outer quotes. Some fail loudly with a ValueError or SyntaxError; others, like %M instead of %m, quietly print the wrong text.
%mvs%M:%mis the month and%Mis minutes, sof"{d:%Y-%M-%d}"prints2024-07-05for 5 March 2024 at 09:07.- Literal braces: double them to print a brace, so
f"{{x}} = {x}"prints{x} = 10whenxis 10. - Numbers stored as text:
f"{'3.5':.2f}"raisesValueError: Unknown format code 'f' for object of type 'str'. Convert withfloat()first. - Rounding surprises:
f"{2.675:.2f}"prints2.67, not 2.68, because 2.675 is stored as a binary float slightly below 2.675. - Reusing the outer quotes: before Python 3.12,
f"{row["name"]}"is aSyntaxError. Use single quotes inside the braces, or see nested f-string quotes.
Pro Tip: F-strings are evaluated at runtime and are the fastest string formatting method in Python. Use {variable=} for quick debugging to see both the variable name and its value.
โ Back to Python Tips