The pprint module formats data structures with proper indentation and line breaks. When print() gives you an unreadable mess, pprint makes it human-friendly.
The Problem
Regular print squashes everything:
data = {'users': [{'name': 'Alice', 'scores': [95, 87, 92]}, {'name': 'Bob', 'scores': [78, 85, 90]}], 'metadata': {'version': 1, 'updated': '2024-01-15'}}
print(data)
# {'users': [{'name': 'Alice', 'scores': [95, 87, 92]}, {'name': 'Bob', 'scores': [78, 85, 90]}], 'metadata': {'version': 1, 'updated': '2024-01-15'}}Basic Pretty Print
from pprint import pprint
data = {
'users': [
{'name': 'Alice', 'scores': [95, 87, 92]},
{'name': 'Bob', 'scores': [78, 85, 90]}
],
'metadata': {'version': 1, 'updated': '2024-01-15'}
}
pprint(data)Output:
{'metadata': {'updated': '2024-01-15', 'version': 1},
'users': [{'name': 'Alice', 'scores': [95, 87, 92]},
{'name': 'Bob', 'scores': [78, 85, 90]}]}
Controlling Width
Adjust line width:
from pprint import pprint
data = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
# Default width (80)
pprint(data)
# {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
# Narrow width forces wrapping
pprint(data, width=20)
# {'a': 1,
# 'b': 2,
# 'c': 3,
# 'd': 4,
# 'e': 5}Indentation
Control indent level:
from pprint import pprint
data = {'outer': {'inner': {'deep': [1, 2, 3]}}}
pprint(data, indent=4)
# { 'outer': { 'inner': { 'deep': [1, 2, 3]}}}Depth Limiting
Hide deeply nested content:
from pprint import pprint
data = {'level1': {'level2': {'level3': {'level4': 'deep'}}}}
pprint(data, depth=2)
# {'level1': {'level2': {...}}}Getting the String
Use pformat to get the string instead of printing:
from pprint import pformat
data = {'a': [1, 2, 3], 'b': [4, 5, 6]}
formatted = pformat(data)
# Use in logging, files, etc.
with open('debug.txt', 'w') as f:
f.write(formatted)Sorting Keys
Keys are sorted by default in Python 3.8+. Disable it:
from pprint import pprint
data = {'zebra': 1, 'apple': 2, 'mango': 3}
# Default: sorted
pprint(data)
# {'apple': 2, 'mango': 3, 'zebra': 1}
# Preserve insertion order
pprint(data, sort_dicts=False)
# {'zebra': 1, 'apple': 2, 'mango': 3}Compact Mode
Fit more on each line:
from pprint import pprint
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Normal
pprint(data, width=30)
# [1,
# 2,
# 3,
# ...]
# Compact
pprint(data, width=30, compact=True)
# [1, 2, 3, 4, 5, 6, 7,
# 8, 9, 10]PrettyPrinter Class
For repeated use with the same settings:
from pprint import PrettyPrinter
pp = PrettyPrinter(indent=2, width=60, depth=3)
pp.pprint({'data': [1, 2, 3]})
pp.pprint({'more': {'nested': 'data'}})Debugging Example
from pprint import pprint
def debug_response(response):
print("=== API Response ===")
pprint(response, depth=3, width=100)
print("====================")
# Much more readable than print()
debug_response({
'status': 200,
'data': {
'users': [...],
'pagination': {'page': 1, 'total': 100}
}
})With Logging
import logging
from pprint import pformat
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
data = {'complex': {'nested': {'structure': [1, 2, 3]}}}
logger.debug("Received data:\n%s", pformat(data))Custom Objects
pprint works with any object that has a readable __repr__:
from pprint import pprint
class User:
def __init__(self, name, email):
self.name = name
self.email = email
def __repr__(self):
return f"User({self.name!r}, {self.email!r})"
users = [User('Alice', 'alice@example.com'), User('Bob', 'bob@example.com')]
pprint(users)
# [User('Alice', 'alice@example.com'),
# User('Bob', 'bob@example.com')]pprint vs json.dumps
For JSON-like output:
import json
from pprint import pprint
data = {'name': 'Alice', 'scores': [95, 87]}
# pprint: Python repr style
pprint(data)
# {'name': 'Alice', 'scores': [95, 87]}
# json.dumps: JSON style
print(json.dumps(data, indent=2))
# {
# "name": "Alice",
# "scores": [95, 87]
# }Use json.dumps when you need valid JSON. Use pprint for Python debugging.
When to Use pprint
Use pprint when:
- Debugging complex nested structures
- Logging data for human review
- Quick inspection in REPL
- Writing debug output to files
Don't use when:
- You need valid JSON output
- Performance matters (pprint is slower than print)
- Output will be parsed by another program
For readable debugging output, pprint is the quick solution that's always available in the standard library.