You’ve typed print() hundreds of times. But the day you need to print a clean invoice, a log with timestamps, or a progress bar — suddenly that single print() isn’t enough. Let’s fix that today.
If you’ve ever struggled with python print formatting, you’re not alone. Most tutorials show you print("Hello") and move on. But real-world code demands more. You need aligned columns, controlled decimal places, and output that looks professional.
In this guide, you’ll master everything from basic sep and end parameters to advanced f-string format specifiers. We’ll cover debugging tricks, table formatting, and even the latest Python 3.12+ upgrades. By the end, you’ll write python formatted print statements that would make any senior developer proud.
Let’s dive in.

Page Contents
The print() Function — More Than You Think
Most developers think print() just displays text. But it’s actually a powerhouse with five parameters you can control:
print(*objects, sep=' ', end='n', file=sys.stdout, flush=False)
Let’s break down each parameter with real examples you’ll actually use.
The sep Parameter — Custom Separators
By default, print() separates multiple arguments with a space. But you can change this:
print("2026", "03", "30") # output: 2026 03 30
print("2026", "03", "30", sep="-") # output: 2026-03-30
print("2026", "03", "30", sep="/") # output: 2026/03/30
print("home", "user", "docs", sep="/") # output: home/user/docs
print("Arjun", 22, "Ranchi", sep=" | ") # output: Arjun | 22 | Ranchi
Unlike C’s printf() where you embed separators in the format string, Python keeps them separate. This makes your code more readable and easier to modify.
The end Parameter — Control Line Endings
Every print() ends with a newline (n) by default. Change it when you need python print without newline:
print("Loading", end="") # output: Loading
print("...") # output: ...
print("Step 1", end=" ") # output: Step 1
print("Complete") # output: Complete
for i in range(3):
print(".", end="", flush=True) # output: ...
print(" Done") # output: Done
This is crucial for progress indicators and same-line updates.
The file Parameter — Print Beyond the Console
import sys
print("Normal output") # output: Normal output (to console)
print("Error message", file=sys.stderr) # output: Error message (to stderr)
with open("log.txt", "w") as f:
print("Logged data", file=f) # output: (written to log.txt)
The flush Parameter — Force Immediate Output
import time
print("Processing", end="", flush=False) # output: (may be delayed)
time.sleep(1)
print("...done") # output: ...done
print("Processing", end="", flush=True) # output: Processing (immediate)
time.sleep(1)
print("...done") # output: ...done
This matters for CI/CD scripts and long-running processes where you need live feedback.
Now that you’ve mastered the print() parameters, let’s explore the three formatting methods available in Python.
Three Ways to Format a Print Statement in Python
- % operator — Old school, still used in logging
- .format() method — More flexible, great for templates
- f-strings — Modern, recommended for Python 3.6+
Unlike C where printf() is the only option, Python gives you choices. Each has its place. Let’s understand when to use which.
Method 1 — The % Operator (Old School)
name = "Rahul"
age = 25
salary = 45000.50
print("Name: %s" % name) # output: Name: Rahul
print("Age: %d" % age) # output: Age: 25
print("Salary: %f" % salary) # output: Salary: 45000.500000
print("Salary: %.2f" % salary) # output: Salary: 45000.50
print("Name: %s, Age: %d" % (name, age)) # output: Name: Rahul, Age: 25
The %m.nf format specifier controls float precision. Here m is minimum width and n is decimal places.
pi = 3.14159265
print("%10.4f" % pi) # output: 3.1416
print("%-10.4f" % pi) # output: 3.1416
Important: The % operator is still used in Python’s logging module. Why? Performance. It defers string building until the log is actually written:
import logging
logging.info("User %s logged in at %d", username, timestamp) # Correct
Method 2 — The .format() Method
name = "Priya"
age = 28
print("Hello {}".format(name)) # output: Hello Priya
print("Hello {0}, you are {1}".format(name, age)) # output: Hello Priya, you are 28
print("Hello {name}, you are {age}".format(name=name, age=age)) # output: Hello Priya, you are 28
Best Use Case: Reusable template strings. This is where .format() still wins over f-strings:
email_template = """
Dear {name},
Your order #{order_id} has been shipped.
Total: ${total:.2f}
Thank you,
{company}
"""
print(email_template.format(
name="Amit",
order_id=12345,
total=299.99,
company="PyBlog Store"
))
f-Strings — Python Print Formatting in 2026
f-strings (formatted string literals) are the modern standard for python print formatting. Introduced in Python 3.6, they’re faster, cleaner, and more powerful than any previous method.
Basic f-String Syntax
name = "Vikram"
age = 26
print(f"Hello {name}") # output: Hello Vikram
print(f"Age: {age}") # output: Age: 26
print(f"Next year: {age + 1}") # output: Next year: 27
import math
print(f"Pi: {math.pi}") # output: Pi: 3.141592653589793
print(f"2 + 2 = {2 + 2}") # output: 2 + 2 = 4
print(f"Square: {5 ** 2}") # output: Square: 25
text = " Hello World "
print(f"Trimmed: '{text.strip()}'") # output: Trimmed: 'Hello World'
print(f"Upper: {text.upper()}") # output: Upper: HELLO WORLD
print(f"Length: {len(text)}") # output: Length: 15
user = {"name": "Anjali", "city": "Ranchi"}
print(f"User: {user['name']} from {user['city']}") # output: User: Anjali from Ranchi
colors = ["Red", "Green", "Blue"]
print(f"First: {colors[0]}, Last: {colors[-1]}") # output: First: Red, Last: Blue

If you’re new to strings in Python, check out our Python Strings guide for more fundamentals.
The Format Specifier Mini-Language
{value:format_spec}
1. Alignment with Fill Characters
name = "Ravi"
print(f"|{name:<10}|") # output: |Ravi |
print(f"|{name:>10}|") # output: | Ravi|
print(f"|{name:^10}|") # output: | Ravi |
print(f"|{name:*<10}|") # output: |Ravi******|
print(f"|{name:*>10}|") # output: |******Ravi|
print(f"|{name:*^10}|") # output: |***Ravi***|
2. Width (Minimum Field Width)
num = 42
print(f"|{num:5}|") # output: | 42|
print(f"|{num:10}|") # output: | 42|
3. Float Precision
pi = 3.14159265359
print(f"{pi:.2f}") # output: 3.14
print(f"{pi:.4f}") # output: 3.1416
print(f"{pi:.6f}") # output: 3.141593
large = 1234567.89
print(f"{large:.2e}") # output: 1.23e+06
ratio = 0.8567
print(f"{ratio:.2%}") # output: 85.67%
4. Integer Types
num = 255
print(f"{num:d}") # output: 255 (decimal)
print(f"{num:b}") # output: 11111111 (binary)
print(f"{num:o}") # output: 377 (octal)
print(f"{num:x}") # output: ff (hex lowercase)
print(f"{num:X}") # output: FF (hex uppercase)
print(f"{num:#x}") # output: 0xff
5. Thousands Separator
population = 1420000000
print(f"{population:,}") # output: 1,420,000,000
print(f"{population:_}") # output: 1_420_000_000
salary = 1250000.50
print(f"₹{salary:,.2f}") # output: ₹1,250,000.50
6. Zero Padding
day = 5
month = 3
print(f"{day:02d}") # output: 05
print(f"{month:02d}") # output: 03
7. Sign Display
temp = 25
print(f"{temp:+d}") # output: +25
print(f"{temp: d}") # output: 25
temp = -10
print(f"{temp:+d}") # output: -10
8. String Truncation
text = "Hello World Python"
print(f"{text:.5s}") # output: Hello
print(f"{text:.10s}") # output: Hello Worl
The = Debugging Specifier (Python 3.8+)
x = 42
y = 100
print(f"{x=}") # output: x=42
print(f"{y=}") # output: y=100
print(f"{x=}, {y=}") # output: x=42, y=100
pi = 3.14159265359
print(f"{pi=:.2f}") # output: pi=3.14
salary = 1250000
print(f"{salary=:,}") # output: salary=1,250,000
Python 3.12 f-String Upgrades (PEP 701)
If you’re running python 3.12 f-strings or Python 3.13, you got major upgrades. The biggest change: same-quote nesting.
# Python 3.12+ - now works:
name = "Rahul"
print(f'Hello {name}'s friend') # output: Hello Rahul's friend
For more details, check the official Python documentation on f-strings.
Printing Tables and Columns in Python
Creating aligned tables is a common need for reports, invoices, and data displays. This targets print format columns python searches.
students = [
{"name": "Amit Kumar", "math": 95, "science": 88, "english": 92},
{"name": "Priya Singh", "math": 87, "science": 94, "english": 89},
{"name": "Rahul Verma", "math": 92, "science": 85, "english": 90},
]
print(f"{'Name':<20} {'Math':>6} {'Science':>9} {'English':>9} {'Total':>7}")
print("-" * 55)
for student in students:
total = student["math"] + student["science"] + student["english"]
print(f"{student['name']:<20} {student['math']:>6} {student['science']:>9} {student['english']:>9} {total:>7}")
print("-" * 55)
pprint — When print() Isn’t Enough
import pprint
api_response = {
"user": {"name": "Arjun", "age": 22, "city": "Ranchi"},
"scores": [88, 92, 75, 95, 68],
"metadata": {"source": "exam_2026", "verified": True}
}
pprint.pprint(api_response) # Nicely formatted
pprint.pprint(api_response, depth=1) # Collapse nested structures
formatted = pprint.pformat(api_response) # Get as string for logging
Real-World Examples (Put It All Together)
Example 1: Progress Indicator
import time
tasks = ["Connecting to DB", "Loading config", "Starting server"]
for task in tasks:
print(f" ⏳ {task}...", end=" ", flush=True)
time.sleep(0.5)
print("✅")
Example 2: Invoice Generator
items = [
("Python Course", 1, 2999.00),
("VS Code Theme", 3, 149.00),
("Docker eBook", 2, 499.00),
]
print(f"n{'INVOICE':^40}")
print("=" * 40)
print(f"{'Item':<20} {'Qty':>5} {'Price':>8} {'Total':>8}")
print("-" * 40)
grand_total = 0
for name, qty, price in items:
total = qty * price
grand_total += total
print(f"{name:<20} {qty:>5} {price:>8.2f} {total:>8.2f}")
print("-" * 40)
print(f"{'Grand Total':>34} {grand_total:>8.2f}")
print("=" * 40)
Example 3: Log Line Formatter
from datetime import datetime
def log(level, message):
ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
levels = {"INFO": "ℹ️ ", "WARN": "⚠️ ", "ERROR": "❌ "}
icon = levels.get(level, " ")
print(f"[{ts}] {level:<5} {icon} {message}")
log("INFO", "Server started on port 8080")
log("WARN", "Memory usage above 80%")
log("ERROR", "Database connection failed")

Practice Challenge
Test your understanding! Fill in the blanks to complete this code:
# Complete the f-string below
name = "Rohan"
score = 87.654
items = ["Python", "Java", "Go"]
# 1. Print name with 15 character width, left-aligned
print(f"{_____:<15}")
# 2. Print score with exactly 2 decimal places
print(f"{_____:____}")
# 3. Use the debug specifier to show items variable
print(f"{_____}")
# 4. Print all three languages separated by " | "
print(f"{_____}")
Expected Output:
Rohan 87.65 items=['Python', 'Java', 'Go'] Python | Java | Go
Click here for the solution
print(f"{name:<15}") # Left-aligned, 15 chars
print(f"{score:.2f}") # 2 decimal places
print(f"{items=}") # Debug specifier
print(f"{' | '.join(items)}") # Join with separator
Key Takeaways
- print() parameters: Master
sep,end,file, andflushfor complete control - f-strings are the standard: Use them for all new Python 3.6+ code
- Format specifiers: Learn
<>^alignment,.nfprecision,,separators - Debug with =: The
{var=}syntax saves time during debugging - pprint for complex data: Use it for nested dictionaries and API responses
If you’re just starting with Python, check out our Introduction to Python Programming guide for more fundamentals.
Practice makes you Perfect!!

