F-String Formatting in Python

โฑ๏ธ 3 min read ๐Ÿ 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.

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