The Zen of Python: What 'import this' Reveals About Python Philosophy

The Zen of Python: What 'import this' Reveals About Python Philosophy

Open a Python REPL and type:

>>> import this

You'll see:

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

These 19 principles (20 if you count the missing one—more on that later) were written by Tim Peters in 1999. They're codified in PEP 20 and embedded in Python itself.

Beautiful is better than ugly

Code aesthetics matter. Python values clean, well-formatted code that's pleasant to read. This isn't superficial—readable code is maintainable code.

# Ugly
if(x==5):y=x+1

# Beautiful
if x == 5:
    y = x + 1

PEP 8, Python's style guide, enforces this principle. Consistent spacing, naming conventions, and structure make code beautiful.

Explicit is better than implicit

Magic is tempting, but clarity wins. Don't hide behavior behind abstraction that makes the code hard to understand.

# Implicit
from math import *
result = sqrt(16)  # Where did sqrt come from?

# Explicit
import math
result = math.sqrt(16)  # Clear source

The wildcard import (*) pollutes the namespace. Explicit imports show dependencies.

Simple is better than complex

Prefer straightforward solutions. If two approaches solve the same problem, choose the simpler one.

# Complex
result = list(map(lambda x: x * 2, filter(lambda x: x > 0, numbers)))

# Simple
result = [x * 2 for x in numbers if x > 0]

List comprehensions are simpler than chaining map and filter with lambdas.

Complex is better than complicated

This is subtle. "Complex" means dealing with multiple interconnected parts. "Complicated" means confusing and hard to understand.

A system can be complex (many components) but not complicated (each component is clear). Choose complex-but-clear over simple-but-confusing.

For example, a well-designed class hierarchy might be complex, but if each class has a single responsibility and clear interfaces, it's not complicated.

Flat is better than nested

Deep nesting hurts readability. Flatten when possible.

# Nested
if condition1:
    if condition2:
        if condition3:
            do_something()

# Flat
if not condition1:
    return
if not condition2:
    return
if not condition3:
    return
do_something()

Guard clauses reduce nesting and make the logic linear.

Sparse is better than dense

Don't pack too much logic into one line. Give code room to breathe.

# Dense
return [[row[i] for row in matrix] for i in range(len(matrix[0]))]

# Sparse
transposed = []
for i in range(len(matrix[0])):
    column = [row[i] for row in matrix]
    transposed.append(column)
return transposed

The sparse version is longer but easier to understand.

Readability counts

Code is read more often than it's written. Optimize for readers, not writers.

Choose descriptive variable names. Add comments when necessary. Format consistently. Readability isn't optional—it's a design goal.

Special cases aren't special enough to break the rules

Consistency matters more than convenience. Don't add special behavior that violates established patterns.

Python itself follows this. Strings, lists, and tuples all support iteration the same way. There's no special-case syntax for strings—they're sequences like any other.

Although practicality beats purity

But sometimes you need to break the rules. Pragmatism wins when purity becomes an obstacle.

Python 2's print statement violated the "everything is an object" principle, but it was practical. Python 3 fixed this by making print() a function, but the years of print x showed practicality in action.

Errors should never pass silently

Make failures obvious. Don't suppress errors without good reason.

# Bad
try:
    result = risky_operation()
except:
    pass  # Silent failure

# Good
try:
    result = risky_operation()
except SpecificError as e:
    logger.error(f"Operation failed: {e}")
    raise

Bare except clauses hide bugs. Catch specific exceptions and handle them appropriately.

Unless explicitly silenced

But if you're intentionally ignoring an error, make it explicit:

try:
    os.remove(temp_file)
except FileNotFoundError:
    pass  # File already gone, which is fine

The comment shows intent. You're not hiding an error—you're handling an expected condition.

In the face of ambiguity, refuse the temptation to guess

When behavior isn't clear, raise an error. Don't make assumptions.

Python's dynamic typing can create ambiguity. If a function receives unexpected input, it should fail clearly rather than guess at what was meant:

def process(data):
    if not isinstance(data, list):
        raise TypeError(f"Expected list, got {type(data)}")
    # Process list

There should be one-- and preferably only one --obvious way to do it

Python aims for a single, clear solution to common problems. This contrasts with Perl's "there's more than one way to do it" philosophy.

For opening files, use with:

with open("file.txt") as f:
    content = f.read()

You can use open() without with, but the with statement is the obvious, recommended way—it handles cleanup automatically.

Although that way may not be obvious at first unless you're Dutch

This is a joke about Guido van Rossum, Python's creator, who is Dutch. The "obvious" way isn't always immediately apparent. Learning Pythonic idioms takes time.

List comprehensions weren't obvious to newcomers in the 1990s. Now they're standard Python. The obvious solution emerges through learning.

Now is better than never

Don't wait for the perfect solution. Ship working code.

This encourages iteration over paralysis. Write code that works, then improve it.

Although never is often better than *right* now

But don't rush. If you're not ready, wait. A bad implementation can be worse than no implementation.

This tension—act now vs. wait—is deliberate. Use judgment.

If the implementation is hard to explain, it's a bad idea

If you can't explain how your code works in a few sentences, it's probably too complex.

Decorators, for example, have a simple explanation: "functions that modify other functions." If your decorator requires a lengthy explanation, it's doing too much.

If the implementation is easy to explain, it may be a good idea

"May be" is key. Simple explanations suggest good design, but they don't guarantee it. Simplicity is necessary, not sufficient.

Namespaces are one honking great idea -- let's do more of those!

Namespaces prevent name collisions. math.sqrt and numpy.sqrt can coexist because they're in different namespaces.

Python encourages namespaces through modules, classes, and functions. They're fundamental to organizing code.

The Missing Twentieth Principle

There are 19 principles, not 20. The missing one is deliberate—Tim Peters never wrote it. Speculation abounds, but the most common theory is that it's about maintaining a sense of incompleteness, acknowledging that no set of principles captures everything.

The Easter Egg Implementation

If you look at the source of this.py, you'll find the Zen is stored encrypted with ROT13:

s = """Gur Mra bs Clguba, ol Gvz Crgref..."""

The module decodes it when imported. This is a joke—encrypting Python's philosophy about simplicity and explicitness with a trivial cipher. Even the Zen doesn't take itself too seriously.

Living by the Zen

These aren't strict rules. They're guidelines that sometimes contradict each other. "Simple is better than complex" conflicts with "complex is better than complicated." That's intentional. Programming requires judgment.

The Zen helps you make better decisions, but it doesn't make decisions for you.

Further Reading

PEP 20, The Zen of Python, is the official specification.

For practical applications, see PEP 8, the Python style guide, which embodies many Zen principles.

Raymond Hettinger's talk "Beyond PEP 8" explores what makes code Pythonic, with heavy reference to the Zen.

The Zen of Python is short enough to memorize, but understanding it takes years of writing Python.

Wear the code

Product mockup

import this Developer T-Shirt (Python Edition — Dark Mode)

£25.00

View product
Product mockup

import this Developer T-Shirt (Python Edition — Light Mode)

£25.00

View product

0 comments

Leave a comment

Please note, comments need to be approved before they are published.