Learning LibraryCore Coding LibraryTeens

f-strings in Python: format numbers the way people read them

Your model says a tee costs 0.38 a wear and the margin is 0.631578947368421. Both are right, and neither is fit to show anyone. Format specs fix that.

The big idea

An f-string embeds expressions in text inside {}, and a format spec after a colon controls exactly how each value is displayed.

See it in code

1The basics

Rounding changes a number; it doesn't control how it prints. round(0.8, 2) is still displayed as 0.8. A format spec sets the display directly:

python
cheap_per_wear = 8 / 10
print(round(cheap_per_wear, 2))
print(f"${cheap_per_wear:.2f} per wear")
Run it. Rounding, then formatting:
0.8
$0.80 per wear

:.2f means "fixed-point, two decimal places," so 0.8 is shown as 0.80. Rounding removes digits; it never adds them back.

2A step further

Other specs handle other shapes of number. :, inserts thousands separators and :.1% multiplies by 100 and adds a percent sign:

python
margin = (38 - 14) / 38
year_one = 331398
launch_costs = 12500.0

print(f"Margin: {margin:.1%}")
print(f"Year one revenue: ${year_one:,}")
print(f"Launch costs: ${launch_costs:,.0f}")
Run it. Three numbers, three formats:
Margin: 63.2%
Year one revenue: $331,398
Launch costs: $12,500

Specs combine: :,.0f means thousands separators and zero decimal places. The underlying values are unchanged; only their presentation is.

3At Evergreen

A number after the colon sets a field width, with < for left-aligned and > for right-aligned. That's enough to print a tidy table:

python
names = ["Organic tee", "Everyday pants", "Wool socks"]
prices = [38, 78, 14]
costs = [14, 29, 4]

print(f"{'Product':<16}{'Price':>7}{'Margin':>9}")
for i in range(len(names)):
    margin = (prices[i] - costs[i]) / prices[i]
    print(f"{names[i]:<16}{prices[i]:>7.2f}{margin:>9.1%}")
Run it. A catalog in columns:
Product           Price   Margin
Organic tee       38.00    63.2%
Everyday pants    78.00    62.8%
Wool socks        14.00    71.4%

Every row uses the same widths, so the columns line up whatever the lengths of the names. Text reads best left-aligned and numbers right-aligned.

The same idea, everywhere

The same specs format any report: a GC-content percentage, a backtest's return, a file size, a timing. Compute at full precision, and round only when you display.

Try it yourself

Add a fourth column for profit per item, prices[i] - costs[i], formatted as >8.2f. Then widen the first column to 20 and see everything shift together.

The common mistake

Forgetting the f. Without it, "Margin: {margin:.1%}" prints the braces and the spec exactly as typed. The symptom is unmistakable: curly braces on screen.

What it unlocks

f-strings are the polished form of print(). The values going into them often need cleaning first with string methods.

Want the simpler version? Read the Kids version →