New in 2026: Master Python for AI, Data Science

ProgrammingPythonPython Basic Tutorial

Python Print Formatting: The Complete 2026 Guide (f-Strings, sep, end & More)

python-programming-670x335

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.

Comparison of %, .format(), and f-string syntax in Python
Python print formatting comparison chart

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

  1. % operator — Old school, still used in logging
  2. .format() method — More flexible, great for templates
  3. 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
Python f-string syntax showing variable inside curly braces
f-string syntax diagram

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")
Formatted log lines with timestamps, levels, and icons
Python log formatter output example

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, and flush for complete control
  • f-strings are the standard: Use them for all new Python 3.6+ code
  • Format specifiers: Learn <>^ alignment, .nf precision, , 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!!

Related posts
Python

Pydantic Agent Basics: A Complete 2026 Tutorial

ProgrammingPython

Production-Ready MCP Servers — Security, Testing & Deployment

ProgrammingPython

Build Your First MCP Server with Python SDK — Fundamentals

ProgrammingPython

Connect FastAPI to MCP — Two Integration Patterns

Leave a Reply

Worth reading...
Top 10 Python frameworks to learn in 2019