Format numbers for display¶
The question. You have a number and need it as a string a human will read — with thousands separators, a fixed number of decimals, a percent sign, currency, scientific notation, or padded to line up in a column.
The answer is the format mini-language, used inside f-strings after a colon: f'{value:spec}'. One compact spec controls grouping, precision, sign, width, and notation. Here are the pieces you'll actually use; the full grammar is in the number formatting reference.
Fixed decimal places — .Nf¶
.2f means "fixed-point, two decimals". It rounds for display and always shows that many places, even trailing zeros.
print(f'{3.14159:.2f}') # '3.14'
print(f'{2:.2f}') # '2.00' — trailing zeros kept
print(f'{1/3:.4f}') # '0.3333'
Thousands separators — , and _¶
A , inserts comma thousands separators; _ uses underscores. Combine with .2f by writing the grouping before the precision: ,.2f.
print(f'{1234567:,}') # '1,234,567'
print(f'{1234567.5:,.2f}') # '1,234,567.50'
print(f'{1234567:_}') # '1_234_567'
Percentages — %¶
The % type multiplies by 100 and appends a percent sign. Set the decimals as usual.
print(f'{0.1234:.1%}') # '12.3%'
print(f'{0.5:.0%}') # '50%'
print(f'{1/3:.2%}') # '33.33%'
Scientific and general — e and g¶
e forces scientific notation; g ("general") picks fixed or scientific automatically and trims trailing zeros, rounding to significant figures rather than decimal places.
print(f'{1234567:.2e}') # '1.23e+06'
print(f'{0.000123:.2e}') # '1.23e-04'
print(f'{1234567:.3g}') # '1.23e+06'
print(f'{0.000123:.3g}') # '0.000123'
Sign control — +¶
By default only negatives show a sign. + forces a sign on positives too (handy for deltas); a space puts a blank where the + would go, so positive and negative line up.
print(f'{42:+}') # '+42'
print(f'{-42:+}') # '-42'
print(f'{42: }') # ' 42' — space holds the sign column
Width, fill, and alignment¶
A number before the type sets a minimum width; <, >, ^ align left, right, centre; a character before the alignment is the fill. Numbers right-align by default. This is how you make columns line up.
for n in [5, 42, 1337]:
print(f'{n:>6}') # right-aligned in a 6-wide field
print(f'{42:08.2f}') # '00042.00' — zero-padded to width 8
print(f'{"mid":^9}') # ' mid ' — centred
Other bases — b, o, x¶
For integers, b, o, and x format in binary, octal, and hex. The # flag adds the 0b/0o/0x prefix.
print(f'{255:b}') # '11111111'
print(f'{255:x}') # 'ff'
print(f'{255:#x}') # '0xff' — with prefix
print(f'{255:08b}') # '11111111' padded to 8 bits
Putting it together¶
Specs compose, in the order fill/align, sign, #, 0, width, grouping, .precision, type. A realistic example — a right-aligned, signed, comma-grouped currency figure:
value = 1234567.891
print(f'£{value:>15,.2f}') # '£ 1,234,567.89'
# a small table
rows = [('Coffee', 2.5), ('Sandwich', 4.95), ('Cake', 12)]
for name, price in rows:
print(f'{name:<10}{price:>8,.2f}')
Quick reference¶
| Spec | On 1234.5 |
Meaning |
|---|---|---|
.2f |
1234.50 |
fixed, 2 decimals |
,.2f |
1,234.50 |
+ thousands separator |
.1% |
(on 0.1234) 12.3% |
percent |
.2e |
1.23e+03 |
scientific |
.3g |
1.23e+03 |
significant figures |
>10 |
1234.5 |
right-align, width 10 |
08.1f |
001234.5 |
zero-pad to width 8 |
See the number formatting reference for the complete grammar.