DEV Community

Cover image for Python f-strings: Everything You Need to Know (With Examples)
German Yamil
German Yamil

Posted on

Python f-strings: Everything You Need to Know (With Examples)

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))
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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   
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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}")
Enter fullscreen mode Exit fullscreen mode

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']:,}")
Enter fullscreen mode Exit fullscreen mode

!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
Enter fullscreen mode Exit fullscreen mode

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}")
Enter fullscreen mode Exit fullscreen mode

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)}")
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
    )
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.


Further Reading

Top comments (0)