Back to Blog

Python f-strings — 7 Things You Can Do

Celest KimCelest Kim

Video: Python f-strings — 7 Things You Can Do by CelesteAI

Take the quiz on the full lesson page
Test what you've read · interactive walkthrough

An f-string is the modern way to build strings in Python. The f prefix turns the string into a template; anything inside curly braces gets evaluated and dropped in. Most people stop there.

But f-strings have a deeper format-spec mini-language. Number formatting, alignment, percentages, the = debug shortcut, conversion flags, multi-line templates, and date formatting all live inside the same braces. This post walks seven patterns on a tiny demo so you have a mental shelf to reach for next time you build a string.

Setup

from datetime import date

name = "Alice"
price = 1234.5678
count = 42
today = date(2026, 5, 23)

1. Basic interpolation

f"Hello, {name}"
# Hello, Alice

The simplest case. The f prefix makes the string a template; {name} is replaced by the value at runtime.

2. Format spec — numbers, alignment, percentages

f"${price:,.2f}"   # $1,234.57   thousand-separator, 2 decimals
f"|{count:>6}|"    # |    42|    right-pad to width 6
f"{0.1234:.2%}"    # 12.34%      percentage with 2 decimals

After a colon inside the braces comes the format spec — the same mini-language as the old .format method and the format() built-in. Comma for thousand-separator, .2f for fixed-point with 2 decimals, > for right-align with a width, % for percentage.

This is the part most beginners miss. If you’re calling round() or f"{x:.2f}".rstrip("0") before dropping a number into an f-string, the format spec already does it.

3. Expressions inside the braces — not just variables

items = [10, 20, 30]
f"first: {items[0]}"          # first: 10
f"sum:   {sum(items)}"        # sum:   60
f"upper: {name.upper()}"      # upper: ALICE

Anything that evaluates to a value works inside the braces. Method calls. Indexing. Arithmetic. Even ternary expressions and small comprehensions (though the readability of those drops fast).

4. = for debugging (Python 3.8+)

x, y = 10, 20
f"{x=}, {y=}, {x+y=}"
# x=10, y=20, x+y=30

The killer feature for print-debugging. {x=} prints both the expression and its value, separated by =. Saves you from typing the variable name twice — once as a label and once as the value. Works for any expression: {items[0]=}, {sum(items)=}, {x*y=}.

If you’re scattering print(f"x is {x}") calls through your code to figure out what’s wrong, switch to print(f"{x=}") and you’ll see why people love it.

5. !r / !s / !a conversion flags

words = ["python", "lambda"]
f"with str:   {words!s}"      # ['python', 'lambda']
f"with repr:  {words!r}"      # ['python', 'lambda']  (same here)
f"with ascii: {'café'!a}"     # 'caf\xe9'

The bang flags call str(), repr(), or ascii() on the value before formatting. !r is the most useful in practice: it quotes strings in the output, so in debug logs you can tell "" from None and the string "5" from the number 5.

6. Multi-line f-strings

msg = f"""
=== Report ===
name:  {name}
price: ${price:,.2f}
date:  {today}
"""

Triple-quote and embed values across multiple lines. Useful for printing structured reports, building config blocks, or producing multi-line error messages.

7. Date and time formatting — strftime codes inside the spec

f"{today:%Y-%m-%d}"          # 2026-05-23
f"{today:%A, %B %d %Y}"      # Saturday, May 23 2026

The format spec accepts strftime codes for date and datetime values. No need to call today.strftime(...) separately and then drop the result into a regular string. Same story for % (percentage), x (hex), b (binary), e (scientific) — all the format codes from the spec mini-language work here.

The decision

Goal Pattern
Drop a variable in f"{x}"
Number formatting f"{x:,.2f}", f"{x:.2%}"
Method call / expression f"{x.upper()}", f"{sum(xs)}"
Print-debugging f"{x=}"
Quoted in logs f"{x!r}"
Multi-line f"""..."""
Date f"{date:%Y-%m-%d}"

Once you’ve internalized these seven, almost every Python string-building task fits one of them.

Want the deeper dive?

Common Questions Ep 12 — List Comprehensions is a similar “patterns you’ll meet in real code” walk-through for another Python idiom.

Ready? Take the quiz on the full lesson page →
Test what you've learned. Watch the lesson and try the interactive quiz on the same page.