- Master f-strings for modern string formatting
- Understand format specifiers for numbers and alignment
- Use format() method and % operator
- Choose the right formatting approach for each situation
String Formatting
Imagine writing a thank-you letter where you need to insert the recipient's name, the gift they gave you, and the date. You wouldn't write a separate letter for each person – you'd use a template with placeholders!
String formatting is exactly this concept in programming. Instead of awkwardly concatenating strings with +, you create elegant templates where values are inserted automatically. This makes your code readable, maintainable, and professional.
The Evolution of String Formatting
Python has evolved its formatting approaches over time:
String Formatting Evolution
OLD WAY (% operator) - Python 2 style
"Hello %s, you are %d years old" % (name, age)
BETTER WAY (.format() method) - Python 2.6+
"Hello {}, you are {} years old".format(name, age)
BEST WAY (f-strings) - Python 3.6+ ← USE THIS!
f"Hello {name}, you are {age} years old"
F-strings are: Readable, Fast, Modern
F-Strings: The Modern Way
F-strings (formatted string literals) are the cleanest way to format:
Basic Usage
name = "Alice"
age = 25
city = "Paris"
# Simple variable insertion
greeting = f"Hello, {name}!"
print(greeting) # Hello, Alice!
# Multiple variables
intro = f"{name} is {age} years old and lives in {city}."
print(intro) # Alice is 25 years old and lives in Paris.
# Expressions inside braces!
message = f"{name} will be {age + 10} in ten years."
print(message) # Alice will be 35 in ten years.
Expressions in F-Strings
# Math operations
x = 10
print(f"Double of {x} is {x * 2}") # Double of 10 is 20
# Method calls
name = "alice"
print(f"Hello, {name.title()}!") # Hello, Alice!
# Function calls
import math
print(f"Pi is approximately {math.pi:.2f}") # Pi is approximately 3.14
# Conditional expressions
score = 85
print(f"Result: {'Pass' if score >= 60 else 'Fail'}") # Result: Pass
Format Specifiers
Control exactly how values appear:
Number Formatting
# Decimal places
pi = 3.14159265359
print(f"{pi:.2f}") # 3.14 (2 decimal places)
print(f"{pi:.4f}") # 3.1416 (4 decimal places)
print(f"{pi:.0f}") # 3 (no decimal places)
# Thousand separators
big_num = 1234567
print(f"{big_num:,}") # 1,234,567
# Percentage
ratio = 0.856
print(f"{ratio:.1%}") # 85.6%
# Scientific notation
large = 1234567890
print(f"{large:.2e}") # 1.23e+09
Format Specifier Syntax
Format Specifier Syntax
f"{value:fill align width .precision type}"
d, f, s, %, etc
Decimal places
Minimum width
<, >, ^, =
Padding char
Examples:
f"{42:05d}" → "00042" (zero-padded to 5 digits)
f"{3.14:.1f}" → "3.1" (1 decimal place)
f"{'hi':>10}" → " hi" (right-aligned, 10 chars)
Alignment and Padding
text = "Hi"
num = 42
# Width and alignment
print(f"'{text:10}'") # 'Hi ' (default left for strings)
print(f"'{text:<10}'") # 'Hi ' (left-aligned)
print(f"'{text:>10}'") # ' Hi' (right-aligned)
print(f"'{text:^10}'") # ' Hi ' (centered)
# Custom fill character
print(f"'{text:*^10}'") # '****Hi****' (centered, filled with *)
print(f"'{text:-<10}'") # 'Hi--------' (left, filled with -)
# Numbers
print(f"'{num:5}'") # ' 42' (default right for numbers)
print(f"'{num:05}'") # '00042' (zero-padded)
Practical Formatting
Creating Tables
products = [
("Apple", 1.50, 10),
("Banana", 0.75, 25),
("Orange", 2.00, 15)
]
# Header
print(f"{'Product':<10} {'Price':>8} {'Qty':>5}")
print("-" * 25)
# Rows
for name, price, qty in products:
print(f"{name:<10} ${price:>7.2f} {qty:>5}")
# Output:
# Product Price Qty
# -------------------------
# Apple $ 1.50 10
# Banana $ 0.75 25
# Orange $ 2.00 15
Currency and Percentages
def format_invoice(item, price, tax_rate=0.20):
tax = price * tax_rate
total = price + tax
return f"""
Item: {item}
Price: ${price:,.2f}
Tax: ${tax:,.2f} ({tax_rate:.0%})
Total: ${total:,.2f}
"""
print(format_invoice("Laptop", 1299.99))
Date and Time
from datetime import datetime
now = datetime.now()
# Different formats
print(f"{now:%Y-%m-%d}") # 2024-01-15
print(f"{now:%B %d, %Y}") # January 15, 2024
print(f"{now:%I:%M %p}") # 02:30 PM
print(f"{now:%A, %B %d}") # Monday, January 15
The format() Method
Still useful in certain situations:
# Basic usage
greeting = "Hello, {}!".format("Alice")
print(greeting) # Hello, Alice!
# Positional arguments
template = "{} loves {}"
print(template.format("Alice", "Python")) # Alice loves Python
# Named arguments
template = "{name} is {age} years old"
print(template.format(name="Bob", age=30)) # Bob is 30 years old
# Reusing arguments
template = "{0} said hi to {1}. {1} said hi back to {0}."
print(template.format("Alice", "Bob"))
# Alice said hi to Bob. Bob said hi back to Alice.
# When to use format():
# - When the template is defined elsewhere
# - When working with dynamic format strings
# - In Python versions before 3.6
Practical Examples
Example 1: Receipt Generator
def generate_receipt(items):
"""Generate a formatted receipt."""
receipt = []
receipt.append("=" * 35)
receipt.append(f"{'STORE RECEIPT':^35}")
receipt.append("=" * 35)
receipt.append(f"{'Item':<20} {'Price':>10}")
receipt.append("-" * 35)
total = 0
for name, price in items:
receipt.append(f"{name:<20} ${price:>9.2f}")
total += price
receipt.append("-" * 35)
receipt.append(f"{'TOTAL':<20} ${total:>9.2f}")
receipt.append("=" * 35)
return "\n".join(receipt)
items = [("Coffee", 4.50), ("Sandwich", 8.99), ("Cookie", 2.50)]
print(generate_receipt(items))
Example 2: Progress Bar
def show_progress(current, total, width=30):
"""Display a text progress bar."""
percent = current / total
filled = int(width * percent)
bar = "" * filled + "" * (width - filled)
return f"\rProgress: |{bar}| {percent:.1%}"
# Simulate progress
import time
for i in range(101):
print(show_progress(i, 100), end="")
time.sleep(0.05)
Example 3: Data Report
def create_report(title, data):
"""Create a formatted data report."""
report = []
report.append(f"\n{'=' * 50}")
report.append(f"{title:^50}")
report.append(f"{'=' * 50}\n")
for category, values in data.items():
report.append(f" {category.upper()}")
for label, value in values.items():
if isinstance(value, float):
report.append(f" {label:<20}: {value:>10,.2f}")
else:
report.append(f" {label:<20}: {value:>10,}")
report.append("")
return "\n".join(report)
data = {
"Sales": {"Revenue": 125000.50, "Orders": 1523, "Average": 82.07},
"Customers": {"New": 234, "Returning": 892, "Total": 1126}
}
print(create_report("Monthly Report", data))
Key Takeaways
Remember These Points
Use f-strings for modern formatting
f"Hello {name}" - clean, readable, fast!
Format specifiers control appearance
f"{value:width.precision type}"
Number formatting:
.2f (decimals), :, (thousands), :% (percent)
Alignment:
< (left), > (right), ^ (center)
Expressions work inside {}
f"{x * 2}", f"{name.upper()}"
Use .format() when template is separate from values
What's Next?
You've mastered string formatting! In the next lesson, we'll put it all together with working with text – real-world text processing tasks like cleaning data, parsing information, and transforming content.
