
What's the Zen of Python?
What's the Zen of Python? êŽë š

If youâve been learning Python long enough, then youâve likely seen or heard about the Zen of Python. Experienced Pythonistas often refer to it as a source of wisdom and guidance, especially when they want to settle an argument about certain design decisions in a piece of code. Others take these principles even more seriously by considering them a sort of Pythonic decalogue.
In this tutorial, youâll learn where to find the Zen of Python, how it came into existence, and how to interpret its mysterious aphorisms. You donât need to be a Python master to understand the Zen of Python! But you do need to answer an important question: What exactly is the Zen of Python?
In Short: Itâs a Humorous Poem Listing Python Philosophies
According to the Python glossary, which contains definitions of popular terms related to this programming language, the Zen of Python is a:
Python Glossary
Listing of Python design principles and philosophies that are helpful in understanding and using the language. The listing can be found by typing â
import this
â at the interactive prompt.
Indeed, when you type the indicated import
statement into an interactive Python REPL, then youâll be presented with the nineteen aphorisms that make up the Zen of Python:
import this
#
# 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!
The byline reveals the poemâs author, Tim Peters, whoâs a renowned software engineer and a long-standing CPython core developer best known for inventing the Timsort sorting algorithm. He also authored the doctest
and timeit
modules in the Python standard library, along with making many other contributions.
Take your time to read through the Zen of Python and contemplate its wisdom. But donât take the aphorisms literally, as theyâre more of a guiding set of principles rather than strict instructions. Youâll learn about their humorous origins in the next section.
How Did the Zen of Python Originate?
The idea of formulating a single document that would encapsulate Pythonâs fundamental philosophies emerged among the core developers in June 1999. As more and more people began coming to Python from other programming languages, theyâd often bring their preconceived notions of software design that werenât necessarily Pythonic. To help them follow the spirit of the language, a set of recommendations for writing idiomatic Python was needed.
The initial discussion about creating such a document took place on the Python mailing list under the subject The Python Way. Today, you can find this conversation in the official Python-list archive. If you look closely at the first message from Tim Peters in that thread, then youâll notice that he clearly outlined the Zen of Python as a joke. That original form has stuck around until this day:
Tim Peters from mail.python.org
Clearly a job for Guido alone â although I doubt itâs one heâll take on (fwiw, I wish he would too!). Hereâs the outline he would start from, though:
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!There you go: 20 Pythonic FecHH^HTheses on the nose, counting the one Iâm leaving for Guido to fill in. If the answer to any Python design issue isnât obvious after reading those â well, I just give up.
The wink and the playful way of self-censoring some toilet humor are clear giveaways that Tim Peters didnât want anyone to take his comment too seriously.
Note
In case you didnât get the joke, he started to write something like Feces but then used ^H
âwhich represents a Backspace in older text editors like Vimâto delete the last three letters and make the word Theses. Therefore, the intended phrase is 20 Pythonic Theses.
Eventually, these nearly twenty theses got a proper name and were formally codified in a Python Enhancement Proposal document. Each PEP document receives a number. For example, you might have stumbled on PEP 8, which is the style guide for writing readable Python code. Perhaps as an inside joke, the Zen of Python received the number PEP 20 to signify the incomplete number of aphorisms in it.
To win your next argument about what makes good Python code, you can back up your claims with the Zen of Python. If youâd like to refer to a specific aphorism instead of the entire poem, then consider visiting pep20.org, which provides convenient clickable links to each principle.
And, in case you want to learn the poem by heart while having some fun, you can now listen to a song with the Zen of Python as its lyrics. Barry Warsaw (pumpichank
), another core developer involved with Python since its early days, composed and performed this musical rendition. The song became the closing track on a special vinyl record entitled The Zen Side of the Moon, which was auctioned (pyladies
) at PyCon US 2023.
Okay. Now that you have a rough idea of what the Zen of Python is and how it came about, you might be asking yourself whether you should really follow it.
Should You Obey the Zen of Python?
As a tongue-in-cheek comment left on a mailing list, the Zen of Python should be taken with a grain of salt. That being said, itâs a set of reasonable guidelines that many Python developers abide by. Theyâd argue that the Zen of Python promotes elegant, readable, and idiomatic code aligned with the philosophy of the language.
Ultimately, whether you should follow the Zen of Python and to what extent is up to you because the guidelines are open for interpretation. Simply following them wonât magically make your code look Pythonic or help you make an informed design decision, which may depend on the use case. In contrast, the subjective and often seemingly contradictory advice that the Zen of Python provides can leave you feeling more confused than before.
Take the very first principle as an example:
Beautiful is better than ugly.
What does beautiful or ugly mean exactly? How could you possibly measure how beautiful a given code snippet is? After all, one developer might disagree with anotherâs interpretation of beauty.
These other two principles seem to be at odds with each other:
Special cases arenât special enough to break the rules.
Although practicality beats purity.
According to the first one, youâre expected to always stick to the rules without breaking them. But immediately after, the following principle suggests that you should consider the practicality of a solution, even if it sometimes means breaking the rules anyway. Therefore, applying the Zen of Python without violating at least some of its principles is virtually impossible. You must choose between the ones to follow and those to bend or ignore.
Chris Neugebauer (chrisjrn
) gave a relevant talk about the Zen of Python and its limitations at PyCascades 2023, which you can watch online. He explores decorators and type hints as two primary examples of Python design decisions that donât strictly comply with the Zen of Python.
Decorators can help you focus on the codeâs high-level purpose by hiding uninteresting implementation details at the price of making the code more implicit. This complies with the readability principle but fails to favor explicit code. Type hinting, on the other hand, removes implicit behavior by adding complexity, which goes against the Zen of Pythonâs emphasis on simplicity.
Notice how the same feature can simultaneously follow the Zen of Python and not, depending on which angle you look at it from. In many cases, youâll need to strike a balance and decide what makes the most sense for your project.
In conclusion, while the Zen of Python provides useful guidelines, you shouldnât strictly adhere to it as a set of rules etched in stone. Instead, you should prioritize practicality and adapt your approach to the problem at hand. Consider other factors such as performance, business requirements, and team conventions when deciding whether to adhere to these opinionated guidelines.
How Can You Interpret Some of the Aphorisms?
The Zen of Python consists of nineteen aphorisms, some of which favor one specific trait over another, providing opinions about what makes your code better:
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!
In this section, youâll take a closer look at these guidelines, trying to come up with sensible interpretations for them.
The first principle in the Zen of Python states that:
Beautiful is better than ugly.
While beauty is in the eye of the beholder, itâs undeniable that one of the factors behind Pythonâs popularity, particularly in the data science community, is its approachable and aesthetically pleasing syntax. Consider the following function, which creates a sine wave with the specified amplitude, angular frequency, and phase shift:
from math import sin
def sinusoid(A, Ï, Ï):
return lambda t: A * sin(Ï * t + Ï)
This code reads almost like a mathematical formula thanks to Pythonâs compact syntax, which doesnât get in your way. The use of Greek letters in variable names, so common in these types of equations, instantly makes the code relatable to anyone familiar with the underlying theory. Finally, the lambda expression makes the code concise while maintaining readability. As you can see, Pythonâs clarity and expressive power can be hard to beat.
The second principle in the Zen of Python says:
Explicit is better than implicit.
This statement emphasizes the need for your code to be clear and easy to understand rather than relying on unspoken assumptions or hidden rules. For example, when you define a function, itâs much better to explicitly state the expected types of input parameters and the return value instead of forcing whoever reads your code to guess:
from math import sin
from typing import Callable, TypeAlias
Amplitude: TypeAlias = float
AngularFrequency: TypeAlias = float
PhaseShift: TypeAlias = float
Time: TypeAlias = float
SineWave: TypeAlias = Callable[[Time], float]
def sinusoid(A: Amplitude, Ï: AngularFrequency, Ï: PhaseShift) -> SineWave:
"""Return a function that computes the sine wave at a given time."""
return lambda t: A * sin(Ï * t + Ï)
Here, youâve defined several type aliases with meaningful names and used them as type hints in your functionâs parameters to help clarify their purpose and intended use. Youâve also added a docstring explaining what your function returns. Now, anyone looking at your code should have a good idea of what it does and how to use it.
Note
In case you havenât seen type hints in Python before, the colons (:
) in the code snippet above separate variable names from their corresponding data types. In other words, A: Amplitude
means that the parameter A
should have type Amplitude
, and Amplitude: TypeAlias
means that Amplitude
is a type alias for some other typeâin this case, float
.
The next two principles from the Zen of Python are:
Simple is better than complex.
Complex is better than complicated.
The simplest solutions are often the most elegant and efficient. This truth has been known since the Renaissance, as the famous saying âsimplicity is the ultimate sophisticationâ is often attributed to Leonardo da Vinci.
Simplicity may not always be possible, though, as some systems are complex by nature, consisting of many moving parts and layers. But that doesnât mean they have to be complicated or difficult to understand. You can often break a bigger problem down into smaller and more manageable subproblems. Python offers a variety of tools to help you with that, such as list comprehensions, generators, iterators, and more.
Another pair of guidelines from the Zen of Python is the following:
Flat is better than nested.
Sparse is better than dense.
When it comes to the structure of your code, itâs generally preferable to keep things flat by avoiding deeply nested structures. In an earlier example, the lambda expression replaced an inner function, which might have looked like this:
# ...
def sinusoid(A: Amplitude, Ï: AngularFrequency, Ï: PhaseShift) -> SineWave:
"""Return a function that computes the sine wave at a given time."""
def wave(t: Time) -> float:
return A * sin(Ï * t + Ï)
return wave
This code is slightly more explicit and easier to understand, but itâs also nested and verbose. If you had multiple indentation levels nested inside one another, then it could quickly become cluttered and harder to follow.
On the other side of the spectrum, you might feel tempted to cram as much code as possible into a single line. This is where the second statement comes in. Instead of using one long line of dense code, itâs usually better to spread the individual instructions out, making them easier to reason about:
def dense(A, f, Ï):
return lambda t: A * sin(2 * Ï * f * t + Ï)
def sparse(A, f, Ï):
Ï = 2 * Ï * f
return lambda t: A * sin(Ï * t + Ï)
In this case, the sparse()
function breaks a long formula into smaller parts by extracting the independent terms onto a separate line. While you now have more lines of code to read in the vertical direction, each is shorter and easier to comprehend individually.
The final two principles offering qualitative advice are:
Now is better than never.
Although never is often better than right now.
The first one encourages you to take action by trying to implement a working prototype. By the way, Python is an excellent tool for prototyping! You can always keep iterating on your solution without falling into the premature optimization trap, which Donald Knuth famously called âthe root of all evilâ in computer science.
At the same time, you shouldnât make decisions too hastily, rushing into implementation without giving it at least some thought. Practicing patience can save you from investing your time and effort in something that wonât return the desired results. Your intuition may be wrong, so thereâs no point in working on something that ouâre not going to need in the first place.
As you can tell, mastering the Zen of Python means carefully considering each piece of advice, even when the aphorisms may seem contradictory. While going through each and every line is beyond the scope of this tutorial, the more you work with Python, the more intuitive these proverbs will become.
What Inside Jokes Does the Zen of Python Hide?
While the Zen of Python started as a joke, the humor doesnât end there. Python is known for having lots of witty references sprinkled throughout the language. After all, its very name is a tribute to the Monty Python comedy group, and the official documentation is full of puns that allude to their numerous sketches. For example, spam
is a common placeholder name used instead of the more traditional foobar
as an informal nod to the Spam sketch.
Fun Fact
The modern meaning of spam as unwanted digital communication also stems from that classic Monty Python sketch, which excessively repeats the word spam.
Thereâs a funny story about the phrase import this, which Barry Warsaw documented on his blog. In a nutshell, the phrase was chosen from hundreds of community submissions for a slogan that could be printed on a T-shirt for a Python conference in 2001. At the very last minute, Barry got the idea to actually implement this.py
and sneak it into the next Python release without telling anyone. The module would show the Zen of Python when imported.
To make the Zen of Python more difficult to find in Pythonâs source code (python/cpython
), Barry and his small group of accomplices added the module with notifications disabled. They kept it to themselves and even went so far as to obfuscate the code using the ROT-13 substitution cipher to conceal their secret message. It wasnât until much later that someone finally discovered the hidden module.
Note
Displaying the Zen of Python after importing this
is just one of many Easter eggs smuggled into Python, but there are several more eggs awaiting discovery. You can get a head start by downloading the following guide:
Have you found others? Share them in the comments below!
Ironically, when you look more closely at this.py
(python/cpython
) in the Python source code, then youâll immediately notice that it violates many of the Zen of Python principles itself:
s = """Gur Mra bs Clguba, ol Gvz Crgref
Ornhgvshy vf orggre guna htyl.
Rkcyvpvg vf orggre guna vzcyvpvg.
Fvzcyr vf orggre guna pbzcyrk.
Pbzcyrk vf orggre guna pbzcyvpngrq.
Syng vf orggre guna arfgrq.
Fcnefr vf orggre guna qrafr.
Ernqnovyvgl pbhagf.
Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.
Nygubhtu cenpgvpnyvgl orngf chevgl.
Reebef fubhyq arire cnff fvyragyl.
Hayrff rkcyvpvgyl fvyraprq.
Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.
Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.
Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.
Abj vf orggre guna arire.
Nygubhtu arire vf bsgra orggre guna *evtug* abj.
Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.
Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.
Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!"""
d = {}
for c in (65, 97):
for i in range(26):
d[chr(i+c)] = chr((i+13) % 26 + c)
print("".join([d.get(c, c) for c in s]))
This module doesnât look particularly beautiful or readable due to the obfuscation, making its implementation hard to explain. Furthermore, single-letter variable names arenât explicit, and declaring them in the global scope ignores namespaces altogether. Finally, thereâs a simpler way to decode the message using the codecs
module instead of manually implementing the algorithm with nested loops that arenât flat.
Thereâs yet another Easter egg hiding right before your eyes. One of the principles in the Zen of Python is a playful reference to Guido van Rossum, the creator of Python, whoâs originally from the Netherlands:
Although that way may not be obvious at first unless youâre Dutch.
Guido is also known as the Benevolent Dictator for Life (BDFL) of Python, enjoying a great deal of respect and having influence over the language and its evolution. In 2018, he officially stepped down from that role, but he remains a key figure in the Python community.
The Zen of Pythonâs author has a great sense of humor. A long time ago, someone opened a ticket in Pythonâs old bug tracker to point out a punctuation error in another principle. The mistake is in the inconsistent use of the em dashes (â
) in the following sentence:
There should be oneâ and preferably only one âobvious way to do it.
However, that mistake was intentional! The joke, as explained by Tim Peters himself, is that thereâs disagreement about whether you should use spaces around em dashes or not:
from bugs.python.org
Iâm afraid you missed the joke đ While you believe spaces are required on both sides of an em dash, there is no consensus on this point. For example, most (but not all) American authorities say /no/ spaces should be used. Thatâs the joke. In writing a line about âonly one way to do itâ, I used a device (em dash) for which at least two ways to do it (with spaces, without spaces) are commonly used, neither of which is obvious â and deliberately picked a third way just to rub it in.
This will never change đ
Apart from that, this aphorism directly addresses Perl programmers, whose motto was âthere is more than one way to do it,â often abbreviated to TIMTOWTDI and pronounced Tim Toady. During the 1990s and early 2000s, Perl and Python were fierce competitors, and their respective communities had a friendly rivalry. The Zen of Python was actually created as a subtle way to poke fun at Perl.
So, there you have it. Zenâs twenty principles, only nineteen of which have been written down, are full of clever jokes and references that only a true Pythonista will appreciate. Now you can consider yourself one of them!
Conclusion
In this tutorial, youâve explored the Zen of Python, a humorous poem listing opinionated Python philosophies authored by Tim Peters. Along the way, youâve learned how it originated, what some of its aphorisms mean, and whether you should follow them.
Youâve also uncovered several inside jokes and references hidden in the Zen of Python, which is now an important part of Pythonâs culture. Now that you know the story behind it, why donât you take a few minutes and read the Zen of Python one more time to appreciate its true brilliance?
