- Old Style % — the traditional way
- format() method — more powerful and flexible
- f-strings — the modern, readable way
- Template strings — safe formatting for user input
- Which to use — choosing the right method
- Real-world examples — practical applications
What is String Formatting?
String formatting is how you create strings with dynamic content. Instead of hardcoding everything, you create a template with placeholders and fill them with values later. This is one of the most common tasks in programming.
Think of it like a mad libs game. You have a story with blanks, and you fill in the blanks with words to create a unique story. String formatting works the same way — you have a string with placeholders, and you fill them with your data.
Python gives you several ways to do this, from the old % style to modern f-strings. Each has its strengths, and knowing all of them will make you a better Python developer.
💡 Key concept: String formatting is about making your strings dynamic. Instead of writing "Hello, Alice" directly, you write a template and fill in the name later. This makes your code more flexible and maintainable.
Old Style: % Formatting
The Traditional Way
# The % operator is the oldest way to format strings in Python
# 1. Basic formatting
name = "Alice"
age = 25
message = "Hello, %s! You are %d years old." % (name, age)
print(message) # Hello, Alice! You are 25 years old.
# 2. Format specifiers
# %s - string
# %d - integer
# %f - float
# %.2f - float with 2 decimal places
# %x - hexadecimal
score = 85.5
print("Score: %.2f" % score) # Score: 85.50
# 3. Multiple placeholders
item = "book"
price = 19.99
quantity = 3
total = price * quantity
order = "Item: %s, Price: $%.2f, Quantity: %d, Total: $%.2f" % (item, price, quantity, total)
print(order) # Item: book, Price: $19.99, Quantity: 3, Total: $59.97
# 4. Padding and alignment
print("%10s" % "Hello") # " Hello" (right aligned)
print("%-10s" % "Hello") # "Hello " (left aligned)
print("%05d" % 42) # "00042" (zero padding)
# 5. Formatting with dictionary
data = {"name": "Charlie", "age": 30}
print("Name: %(name)s, Age: %(age)d" % data)
# 6. Using with variables
name = "Bob"
score = 95
print("%s scored %d%%" % (name, score)) # Bob scored 95%
# 7. Multiple types
a = 10
b = 20
print("a = %d, b = %d, sum = %d" % (a, b, a + b))
% formatting key points:
- %s — string placeholder
- %d — integer placeholder
- %f — float placeholder
- Tuple values — values passed as a tuple
- Dictionary values — values passed with keys
Quick Check: What format specifier is used for integers? (Answer: %d)
The format() Method
More Powerful and Flexible
# The format() method is more powerful than % formatting
# 1. Basic formatting
name = "Alice"
age = 25
message = "Hello, {}! You are {} years old.".format(name, age)
print(message) # Hello, Alice! You are 25 years old.
# 2. Positional arguments
print("{} {} {}".format("Python", "is", "awesome")) # Python is awesome
print("{1} {0} {2}".format("Python", "is", "awesome")) # is Python awesome
# 3. Keyword arguments
print("{name} is {age} years old".format(name="Alice", age=25))
# Alice is 25 years old
# 4. Format specifiers
print("{:.2f}".format(3.14159)) # 3.14
print("{:10s}".format("Hello")) # "Hello " (right aligned)
print("{:<10s}".format("Hello")) # "Hello " (left aligned)
print("{:>10s}".format("Hello")) # " Hello" (right aligned)
print("{:^10s}".format("Hello")) # " Hello " (center aligned)
# 5. Number formatting
print("{:d}".format(42)) # 42
print("{:b}".format(42)) # 101010 (binary)
print("{:x}".format(42)) # 2a (hex)
print("{:o}".format(42)) # 52 (octal)
print("{:,}".format(1234567)) # 1,234,567 (with commas)
# 6. Dictionary unpacking
data = {"name": "Bob", "age": 30}
print("{name} is {age} years old".format(**data))
# 7. List indexing
people = ["Alice", "Bob", "Charlie"]
print("First: {0[0]}, Second: {0[1]}, Third: {0[2]}".format(people))
# 8. Mixed arguments
print("{0} is {age} years old".format("Alice", age=25))
format() method key points:
- {} — placeholder
- Positional — {0}, {1}, {2}
- Keyword — {name}, {age}
- Format specifiers — :.2f, :10s, :d
- Dictionary unpacking — **data
Quick Check: How do you format a float to 2 decimal places with format()? (Answer: {:.2f})
Modern Way: f-strings
The Most Readable Way to Format
# f-strings (formatted string literals) are the modern way
# 1. Basic f-string
name = "Alice"
age = 25
message = f"Hello, {name}! You are {age} years old."
print(message) # Hello, Alice! You are 25 years old.
# 2. Expressions inside f-strings
a = 5
b = 3
print(f"{a} + {b} = {a + b}") # 5 + 3 = 8
print(f"{a} * {b} = {a * b}") # 5 * 3 = 15
# 3. Format specifiers
pi = 3.14159
print(f"Pi to 2 decimal: {pi:.2f}") # Pi to 2 decimal: 3.14
print(f"Pi to 4 decimal: {pi:.4f}") # Pi to 4 decimal: 3.1416
# 4. Alignment and padding
name = "Alice"
print(f"{name:>10}") # " Alice" (right aligned)
print(f"{name:<10}") # "Alice " (left aligned)
print(f"{name:^10}") # " Alice " (center aligned)
# 5. Number formatting
number = 1234567
print(f"{number:,}") # 1,234,567
print(f"{number:b}") # 100101101011010000111 (binary)
print(f"{number:x}") # 12d687 (hex)
# 6. Calling functions inside f-strings
name = "alice"
print(f"{name.upper()}") # ALICE
print(f"{len(name)}") # 5
# 7. Multi-line f-strings
name = "Bob"
age = 30
message = f"""
Name: {name}
Age: {age}
"""
print(message)
# 8. Dictionary inside f-strings
person = {"name": "Charlie", "age": 35}
print(f"{person['name']} is {person['age']} years old")
f-strings key points:
- f prefix — f"..."
- Expressions — any Python expression inside {}
- Readable — variables are directly in the string
- Fast — faster than other methods
- Python 3.6+ — requires Python 3.6 or later
Quick Check: What version of Python introduced f-strings? (Answer: Python 3.6)
Template Strings
Safe Formatting for User Input
# Template strings are safer for user-provided input
from string import Template
# 1. Basic template
t = Template("Hello, $name!")
print(t.substitute(name="Alice")) # Hello, Alice!
# 2. Multiple placeholders
t = Template("$name is $age years old")
print(t.substitute(name="Bob", age=30)) # Bob is 30 years old
# 3. Using safe_substitute (doesn't raise errors for missing values)
t = Template("$name is $age years old")
print(t.safe_substitute(name="Charlie")) # Charlie is $age years old
# 4. Templates with dictionaries
data = {"name": "David", "age": 28}
t = Template("$name is $age years old")
print(t.substitute(data)) # David is 28 years old
# 5. Templates with $$ for literal dollar sign
t = Template("Price: $$$price")
print(t.substitute(price=19.99)) # Price: $19.99
# 6. When to use templates
# - When users provide the format string
# - When you need safe substitution
# - When you don't need complex formatting
# 7. Comparison with other methods
# Templates are simpler and safer, but less powerful
Template strings key points:
- $placeholder — placeholder syntax
- substitute() — raises error if missing
- safe_substitute() — leaves placeholders if missing
- Safer — good for user-provided templates
- Less powerful — but more secure
Quick Check: When should you use template strings? (Answer: When users provide the format string)
Which Method to Use?
Choosing the Right Tool
# Comparing all four formatting methods
name = "Alice"
age = 25
score = 95.5
# 1. Old style %
print("1. % Style: %s is %d years old with %.1f%% score" % (name, age, score))
# 2. format() method
print("2. format(): {} is {} years old with {:.1f}% score".format(name, age, score))
# 3. f-strings (Python 3.6+)
print(f"3. f-string: {name} is {age} years old with {score:.1f}% score")
# 4. Template strings (from string import Template)
from string import Template
t = Template("4. Template: $name is $age years old with $score% score")
print(t.substitute(name=name, age=age, score=score))
# When to use each:
# Use % formatting when:
# - Working with older Python code
# - You need to keep it simple
# Use format() when:
# - You need more control
# - You're working with Python 3.0+
# Use f-strings when:
# - You're using Python 3.6+
# - You want the most readable code
# - You need speed
# Use Template strings when:
# - Users provide the template
# - You need safe formatting
# - You don't need complex formatting
# Performance comparison:
# f-strings > format() > % > Template
Method comparison:
- f-strings — fastest, most readable, Python 3.6+
- format() — flexible, Python 3.0+
- % formatting — old style, still works
- Template strings — safest for user input
Quick Check: Which formatting method is fastest? (Answer: f-strings)
Try It Yourself
Experiment with string formatting methods in the editor below.
STRING FORMATTING PRACTICE
========================================
1. % FORMATTING
Hello, Alice! You are 25 years old.
Score: 95.50
2. FORMAT() METHOD
Hello, Alice! You are 25 years old.
Score: 95.50
3. F-STRINGS
Hello, Alice! You are 25 years old.
Score: 95.50
4. TEMPLATE STRINGS
Hello, Alice! You are 25 years old.
5. ADVANCED FORMATTING
Item: Book, Price: $19.99, Quantity: 3, Total: $59.97
Number with commas: 1,234,567
String formatting practice complete!
You've Got It!
You now know all the ways to format strings in Python. From old style % to modern f-strings, you can choose the right method for any situation.
Quick Quiz
Test what you've learned:
Frequently Asked Questions
What is the difference between % formatting and f-strings?
Can I use f-strings in older Python versions?
What is the difference between format() and f-strings?
What's a common interview question about string formatting?
When should I use Template strings?
Can I use format specifiers with f-strings?
Where to Go From Here
Now that you understand string formatting, check out these related topics:
String Methods
Explore Python's powerful string methods.
Learn More →📝 Assignments
Practice what you've learned with assignments.
Learn More →Regular Expressions
Learn advanced pattern matching with regex.
Learn More →