Python f-strings: Everything You Need to Know (With Examples)
f-strings (formatted string literals) have been in Python since 3.6. They're faster than .format(), more readable than % formatting, and support any expression inline.
Here's everything they can do.
๐ Free: AI Publishing Checklist โ 7 steps in Python ยท Full pipeline: germy5.gumroad.com/l/xhxkzz (pay what you want, min $9.99)
The basics
name = "Alice"
age = 30
# f-string (modern)
print(f"Hello, {name}! You are {age} years old.")
# .format() (older)
print("Hello, {}! You are {} years old.".format(name, age))
# % formatting (oldest)
print("Hello, %s! You are %d years old." % (name, age))
Any variable or expression inside {} is evaluated and inserted.
Expressions inside {}
f-strings evaluate full Python expressions, not just variable names:
x = 10
y = 3
print(f"{x} + {y} = {x + y}") # 10 + 3 = 13
print(f"{x} * {y} = {x * y}") # 10 * 3 = 30
print(f"{'hello'.upper()}") # HELLO
print(f"{[1, 2, 3, 4, 5][2]}") # 3
print(f"{len('Python')}") # 6
print(f"{'yes' if x > 5 else 'no'}") # yes
# Method calls
items = ["apple", "banana", "cherry"]
print(f"Items: {', '.join(items)}") # Items: apple, banana, cherry
Number formatting
price = 9.99
views = 1234567
ratio = 0.0731
# Fixed decimal places
print(f"Price: ${price:.2f}") # Price: $9.99
print(f"Ratio: {ratio:.4f}") # Ratio: 0.0731
# Percentage
print(f"CTR: {ratio:.1%}") # CTR: 7.3%
# Thousands separator
print(f"Views: {views:,}") # Views: 1,234,567
print(f"Views: {views:_}") # Views: 1_234_567 (Python 3.10+)
# Scientific notation
print(f"{1234567:.2e}") # 1.23e+06
# Zero-padding
print(f"Chapter {3:02d}") # Chapter 03
print(f"Chapter {3:05d}") # Chapter 00003
# Hex, binary, octal
n = 255
print(f"hex: {n:#x}") # hex: 0xff
print(f"bin: {n:#b}") # bin: 0b11111111
print(f"oct: {n:#o}") # oct: 0o377
String alignment and padding
label = "Status"
value = "done"
# Left align (default for strings)
print(f"{label:<15} {value}") # Status done
# Right align
print(f"{label:>15} {value}") # Status done
# Center
print(f"{label:^15} {value}") # Status done
# Fill with custom character
print(f"{label:=^20}") # =======Status=======
print(f"{label:-<20}") # Status--------------
# Build a table
tasks = [
("ch01", "Introduction", "done"),
("ch02", "Architecture", "running"),
("ch03", "Validation", "pending"),
]
print(f"{'ID':<6} {'Name':<20} {'Status':<10}")
print("-" * 36)
for id_, name, status in tasks:
print(f"{id_:<6} {name:<20} {status:<10}")
# ID Name Status
# ------------------------------------
# ch01 Introduction done
# ch02 Architecture running
# ch03 Validation pending
Dates and times
from datetime import datetime, date
now = datetime.now()
today = date.today()
print(f"Date: {today}") # Date: 2026-05-03
print(f"DateTime: {now:%Y-%m-%d %H:%M}") # DateTime: 2026-05-03 19:45
print(f"Time only: {now:%H:%M:%S}") # Time only: 19:45:23
print(f"Human: {now:%B %d, %Y}") # Human: May 03, 2026
print(f"Short: {now:%m/%d/%y}") # Short: 05/03/26
print(f"ISO: {now:%Y-%m-%dT%H:%M:%SZ}") # ISO: 2026-05-03T19:45:23Z
The = specifier (debugging)
Python 3.8+ added {expr=} which prints both the expression and its value:
x = 42
items = [1, 2, 3]
print(f"{x=}") # x=42
print(f"{len(items)=}") # len(items)=3
print(f"{x * 2 + 1=}") # x * 2 + 1=85
# Combined with format spec
price = 9.987654
print(f"{price=:.2f}") # price=9.99
Useful for quick debugging without writing print(f"x = {x}") repeatedly.
Quotes inside f-strings
# Use different quote types
name = "World"
print(f"Hello, {'World'!r}") # Hello, 'World'
print(f'Say {"hello"}') # Say hello
# Python 3.12+: nested same-type quotes are allowed
# print(f"{'hello'}") # works in 3.12+
# For earlier versions, use a variable or different quote style
greeting = "hello"
print(f"Say {greeting}")
Multiline f-strings
title = "My Article"
views = 1250
tags = ["python", "beginners", "tutorial"]
# Implicit string concatenation (one line each)
report = (
f"Title: {title}\n"
f"Views: {views:,}\n"
f"Tags: {', '.join(tags)}"
)
print(report)
# Triple-quoted f-string
summary = f"""
Article: {title}
Views: {views:,}
Tags: {', '.join(tags)}
""".strip()
print(summary)
# Dict access inside f-string
article = {"title": "My Article", "views": 1250}
print(f"Title: {article['title']}, Views: {article['views']:,}")
!r, !s, !a conversion flags
name = "Alice"
data = {"key": "value"}
print(f"{name!r}") # 'Alice' โ repr(), adds quotes
print(f"{name!s}") # Alice โ str() (default)
print(f"{data!r}") # {'key': 'value'}
# Useful for debugging strings with special characters
text = "line1\nline2\ttabbed"
print(f"{text}") # prints with actual newline and tab
print(f"{text!r}") # 'line1\nline2\ttabbed' โ shows escapes
Real-world patterns
Log messages with context:
import logging
def process_task(task_id: str, chapter: int, total: int) -> None:
logging.info(f"[{task_id}] Processing chapter {chapter}/{total}")
try:
# ... do work ...
logging.info(f"[{task_id}] โ
Chapter {chapter} complete")
except Exception as e:
logging.error(f"[{task_id}] โ Chapter {chapter} failed: {e}")
Status table for pipeline output:
def print_pipeline_status(tasks: list[dict]) -> None:
print(f"\n{'ID':<8} {'Name':<25} {'Status':<12} {'Retries'}")
print("โ" * 55)
for t in tasks:
status = t['status']
icon = {"done": "โ
", "running": "โถ", "pending": "โณ", "failed": "โ"}.get(status, "?")
print(f"{t['id']:<8} {t['name']:<25} {icon} {status:<10} {t.get('retries', 0)}")
File path building:
from pathlib import Path
chapter_id = "ch03"
lang = "en"
version = 2
output = Path(f"chapters/{chapter_id}_{lang}_v{version:02d}.md")
log = Path(f"logs/{chapter_id}_{lang}.log")
print(output) # chapters/ch03_en_v02.md
API response summary:
def summarize_response(resp) -> str:
elapsed_ms = resp.elapsed.total_seconds() * 1000
size_kb = len(resp.content) / 1024
return (
f"[{resp.status_code}] {resp.url[:50]}\n"
f" Time: {elapsed_ms:.0f}ms | Size: {size_kb:.1f}KB"
)
f-string cheat sheet
# Basic
f"{variable}" # insert variable
f"{expression}" # any Python expression
# Numbers
f"{n:.2f}" # 2 decimal places: 3.14
f"{n:,}" # thousands sep: 1,234,567
f"{n:.1%}" # percentage: 73.1%
f"{n:05d}" # zero-pad to 5 digits: 00042
f"{n:e}" # scientific: 1.23e+06
f"{n:#x}" # hex with 0x prefix: 0xff
# Strings
f"{s:<20}" # left-align, width 20
f"{s:>20}" # right-align, width 20
f"{s:^20}" # center, width 20
f"{s:-^20}" # center with - fill
# Dates
f"{dt:%Y-%m-%d}" # 2026-05-03
f"{dt:%H:%M:%S}" # 19:45:23
f"{dt:%B %d, %Y}" # May 03, 2026
# Debug
f"{expr=}" # expr=value (Python 3.8+)
f"{s!r}" # repr() โ shows quotes and escapes
Every log line and status message in the pipeline uses f-strings โ they're in every chapter: germy5.gumroad.com/l/xhxkzz โ pay what you want, min $9.99.
Top comments (0)