Essential Python Reading List

2008-02-01, Comments

Snake pic

Here’s my essential Python reading list.

  1. The Zen of Python
  2. Python Tutorial
  3. Python Library Reference
  4. Python Reference Manual
  5. The Python Cookbook
  6. Code Like a Pythonista: Idiomatic Python
  7. Functional Programming HOWTO
  8. Itertools functions
  9. Python library source code
  10. What’s New?

I’ve tried to order the items so you can pause or stop reading at any point: at every stage you’ll have learned about as much possible about Python for the effort you’ve put in.

The Zen of Python

The Zen of Python is so short I can include it here in its entirety. Typing import this in an interpreted session gives a pythonic spin on “Hello, world”.

>>> 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!

If this doesn’t ring true, Python isn’t for you.

Python Tutorial

Your next stop should be the Python tutorial. It’s prominently available at the top of the online documentation tree, with the encouraging prompt:

start here

The latest version (by which I mean the version corresponding to the most recent stable release of Python) can be found on the web at http://docs.python.org, but I recommend you find and bookmark the same page from your local Python installation: it will be available offline, pages will load fractionally quicker, and you’re sure to be reading about the version of Python you’re actually running. (Plus, as I’ll suggest later, it’s well worth becoming familiar with the contents of your Python installation).

And with this tutorial, you’ll be running code right from the start. No need to page through syntax definitions or battle with compiler errors.

Since the best way to learn a language is to use it, the tutorial invites you to play with the Python interpreter as you read.

If you have a programming background you can complete the tutorial in a morning and be using Python by the afternoon; and if you haven’t, Python makes an excellent first language.

A tutorial cannot cover everything, of course, and this one recognises that and points you towards further reading. The next place to look, it says, is the Python Library Reference. I agree.

Python Library Reference

The documentation index suggests you:

keep this under your pillow

It’s a reference. It documents use of the standard libraries which came with your Python installation. I’m not suggesting you read it from cover to cover but you do need to know where it is and what’s in it.

You should definitely read the opening sections which cover the built-in objects, functions and types. I also suggest you get used to accessing the same information from within the Python interpreter using help: it may not be hyperlinked or prettily laid out, but the information is right where you need it.

>>> help(dict)
Help on class dict in module __builtin__:

class dict(object)
 |  dict() -> new empty dictionary.
 |  dict(mapping) -> new dictionary initialized from a mapping object's
 |      (key, value) pairs.
 |  dict(seq) -> new dictionary initialized as if via:
 |      d = {}
 |      for k, v in seq:
 |          d[k] = v
 |  dict(**kwargs) -> new dictionary initialized with the name=value pairs
 |      in the keyword argument list.  For example:  dict(one=1, two=2)

Python Reference Manual

The Language Reference claims to be:

for language lawyers

but I’m not sure that’s true. Readable and clear, it offers a great insight into the language’s design. Again, you may not want to read it straight through, but I suggest you skim read it now and return to it if you find yourself confused by Python’s inner workings.

The Python Cookbook

Python Cookbook cover

The Python Cookbook is the first slab of treeware I’m recommending. Yes, Active State provides a website for the book, which has even more recipes than the book and is well worth a visit, but I’d say you want the printed edition. It’s nicely laid out and provides clear examples of how to use Python for common programming tasks. Alternative approaches are discussed. You can dip in to it or read the sections most relevant to your particular domain. This book teaches you idiomatic Python by example and, remarkably, it actually benefits from being written by a large team of authors. The editors have done an excellent job.

Incidentally, if you’re wondering why I claim Python is a high-level language and C++ isn’t, just compare the contents of the Python Cookbook with the contents of its C++ counterpart. Both books weigh in at ~600 pages, but the C++ one barely gets beyond compiling a program and reading from a file.

Code Like a Pythonista: Idiomatic Python

This one’s a presentation David Goodger gave at a conference last year. I wish he’d written it and I’d read it sooner. If you care about code layout, how you name things etc. but don’t want to waste time arguing about such things, then you probably want to go with the native language conventions. Python has a well-defined style and this presentation describes it well, connecting and summarising the contents of several other references.

Functional Programming HOWTO

The next version of the Python documentation (for versions 2.6 and later) has a HOWTOs section. A. M. Kuchling’s Functional Programming HOWTO is a MUSTREAD, especially for anyone coming from a language with weak support for FP. Python is far from being a pure functional programming language but features like list comprehensions, iterators, generators, even decorators, draw direct inspiration from functional programming.

Itertools functions

If you took my advice and skim-read the Library Reference, you may have skipped past a small module (mis?)filed in the Numeric and Mathematical Modules section. Now’s the time to go back and study it. It won’t take long, but these itertools functions are, to me, the epitome of elegance and power. I use them every day, wish they were promoted to builtins, and most of my interpreted Python sessions start:

>>> from itertools import *

Python library source code

The pure-python modules and test code in your Python installation are packed with good, readable code. If you’re looking for example code using a particular module, have a look at that module’s unit tests.

What’s New?

I’ve mentioned Python versions a few times in this article. Although Python takes stability and backwards compatibility seriously, the language has updated every year for as long as I’ve been using it. Generally, the changes are backwards compatible so, for example, 2.1 code should work fine in 2.5, but it’s important to stay current.

Do you write code like this?

anag_dict = {}

words_fp = open("wordlist.txt", "rt")

for line in words_fp.readlines():
    word = line.strip().lower()
    chars = []
    for ch in word:
        chars.append(ch)
    chars.sort()
    key = "".join(chars)
    anag_dict.setdefault(key, []).append(word)

words_fp.close()

anagrams = []
for words in anag_dict.values():
    if len(words) > 1:
        anagrams.append(words)

Then you should find out about list comprehensions, the built in sorted function, and defaultdicts — introduced in Python 2.0, 2.4, 2.5 respectively!

from collections import defaultdict

anag_dict = defaultdict(list)

with open("wordlist.txt", "rt") as words_fp:
    for line in words_fp:
        word = line.strip().lower()
        key = "".join(sorted(word))
        anag_dict[key].append(word)

anagrams = [words for words in anag_dict.itervalues() 
            if len(words) > 1]

The with statement, incidentally, appears in 2.6, which is in alpha as I write this. Get it now by:

from __future__ import with_statement

Anyway, the point of all this is that A. M. Kuchling writes up what’s new in each Python revision: think of it as the release notes. As an example, here’s What’s New in Python 2.5. Essential reading.

Other Books?

I’ve only mentioned one book on this reading list. There are plenty of other decent Python books but I don’t regard them as essential. In fact, I’d rather invest in an excellent general programming title than (for example) Programming Python.

Why? Well, partly because of the speed at which the language progresses. Thus the second edition of the Python Cookbook — the single book I regard as essential — did a great job of being 2.4 compliant before 2.4 was even released, which definitely extended its shelf-life; but it has nothing to say about Python 2.5 features, let alone Python 2.6 and the transition to Python 3.0. And partly because the books all too easily become too thick for comfortable use. Python famously comes with batteries included, but full details of their use belongs online.

Python Essential Reference cover

I do own a copy of Python Essential Reference by David Beazley. It’s the second edition and is now woefully out of date (covering Python up to version 2.1). I did get good use out of it, though. It’s well designed, beautifully written and laid out, and, weighing in at fewer than 400 pages, comfortable to read and carry. Somehow it manages (managed, I should say) to pack everything in: it’s concise, and it recognises that the online documentation should be the source of authoritative answers. Despite this, I haven’t bought the third edition. Partly because I don’t really need it, partly because it’s now a Python point revision or two out of date, and partly because it’s expanded to 644 pages.

The Reading List, with Links

  1. The Zen of Python
  2. Python Tutorial
  3. Python Library Reference
  4. Python Reference Manual
  5. The Python Cookbook
  6. Code Like a Pythonista: Idiomatic Python
  7. Functional Programming HOWTO
  8. Itertools functions
  9. Python library source code
  10. What’s New
SICP cover picture

There’s nothing controversial here. The Zen of Python should whet your appetite, and the next three items are exactly what you’ll find at the top of the Python documentation home page. Others may argue Python in a Nutshell deserves a place, or indeed the hefty Programming Python, and they’re certainly good books.

I’d be more interested to find out which non-Python books have improved your Python programming the most. For myself, I’ll predictably pick Structure and Interpretation of Computer Programs.


The anagrams puzzle comes from Dave Thomas’s CodeKata, a nice collection of programming exercises. The solutions presented here gloss over a few details and make assumptions about the input. Is “face” an anagram of “café”, for example? For that matter, what about “cafe” and “café”. Or “isn’t” and “tins”? What if the word list contains duplicates? These issues aren’t particularly hard to solve but they do highlight the dangers of coding up a solution without fully specifying the problem, and indeed the difference between a “working” solution and a finished one.

However, I just wanted a short program to highlight advances in recent versions of Python, and in that light, here’s another variant. (My thanks to Marius Gedminas for spotting a bug in the code I originally posted here.)

from itertools import groupby, ifilter, imap
from operator import itemgetter
from string import (ascii_lowercase, ascii_uppercase,
                    punctuation, maketrans, translate)

key = sorted
second = itemgetter(1)

to_lower = maketrans(ascii_uppercase, ascii_lowercase)

data = open("wordlist.txt", "rt").read()
translated = translate(data, to_lower, deletions=punctuation) 
words = set(translated.split())
sorted_words = sorted(words, key=key)
grouped_words = imap(list, imap(second, groupby(sorted_words, key)))
anagrams = ifilter(lambda words: len(words) > 1, grouped_words)