Python f-string Number Formatting

⏱️ 35 sec read 🐍 Python

The format spec inside a Python f-string controls decimals, thousands separators, percentages, padding, and sign — all in a single colon-delimited expression: f"{value:[fill][align][sign][#][0][width][,][.precision][type]}". This page is the cheat sheet you can copy from.

How to Format Decimal Places in a Python f-string

pi = 3.14159265359

f"{pi:.2f}"   # '3.14'
f"{pi:.4f}"   # '3.1416'
f"{pi:.0f}"   # '3'    (rounded to integer, still a string)

# Round-half-to-even (banker's rounding) is used:
f"{2.5:.0f}"  # '2'
f"{3.5:.0f}"  # '4'

How to Format Floats vs Integers

# f = fixed-point float
f"{1234.5:.2f}"   # '1234.50'

# d = integer (errors on a float)
f"{1234:d}"       # '1234'
# f"{1234.5:d}"   -> ValueError

# g = general (drops trailing zeros, switches to scientific for big/small)
f"{1234.5:g}"     # '1234.5'
f"{0.000012345:g}" # '1.2345e-05'

How to Add Thousands Separators

amount = 1234567.891

f"{amount:,}"      # '1,234,567.891'
f"{amount:,.2f}"   # '1,234,567.89'
f"{amount:_.2f}"   # '1_234_567.89'  (PEP 515 underscore separator)

# Locale-aware (uses LC_NUMERIC) — useful for European-style 1.234.567,89:
f"{amount:n}"      # depends on locale.setlocale()

How to Format Percentages

ratio = 0.0857

f"{ratio:.0%}"   # '9%'    (0.0857 -> 8.57 -> rounds to 9)
f"{ratio:.1%}"   # '8.6%'
f"{ratio:.2%}"   # '8.57%'

# Already a percent? Use f and append the symbol manually:
pct = 8.57
f"{pct:.2f}%"    # '8.57%'

Width, Padding, and Alignment

n = 42

f"{n:5d}"        # '   42'    (width 5, right-aligned by default for numbers)
f"{n:<5d}"       # '42   '    (left-align)
f"{n:^5d}"       # ' 42  '    (center)
f"{n:05d}"       # '00042'    (zero-pad)
f"{n:>5d}"       # '   42'    (right-align, explicit)

# Custom fill character:
f"{n:*^7d}"      # '**42***'

# Combine with thousands and decimals:
f"{1234.5:>12,.2f}"  # '    1,234.50'

Forcing the Sign

x = 42
y = -42

f"{x:+d}"   # '+42'   (always show sign)
f"{y:+d}"   # '-42'
f"{x: d}"   # ' 42'   (space for positives, '-' for negatives — aligns columns)
f"{x:-d}"   # '42'    (default: only show '-')

Scientific Notation and Hex/Binary

tiny = 0.000001234

f"{tiny:.2e}"  # '1.23e-06'
f"{tiny:.2E}"  # '1.23E-06'

# Integer bases:
f"{255:b}"     # '11111111'   binary
f"{255:o}"     # '377'        octal
f"{255:x}"     # 'ff'         hex (lowercase)
f"{255:X}"     # 'FF'         hex (uppercase)
f"{255:#x}"    # '0xff'       with prefix

The Format Spec, in Order

Every piece is optional, but they must appear in this order after the colon:

{value:[fill][align][sign][#][0][width][,][.precision][type]}

# Worked example — fill='0', align='>', width=8, comma, .2f:
f"{1234.5:0>8,.2f}"  # '1,234.50'  (already 8 chars, no fill added)
f"{12.5:0>8,.2f}"    # '00012.50'

Common Pitfalls

Pro Tip: Need a dynamic precision? You can nest a variable into the spec: f"{value:.{n}f}" formats with n decimal places, where n is computed at runtime.

← Back to Python Tips