Python Idioms

Idioms for PythonLanguage.


Multiple assignment
  def find_best(key):
    return new_key, value

key, value = find_best(key)

a, b = b, a # swap
Interval test
  if 2 < x < 4:
    print "x is between 2 and 4."
Set membership test
  if val in ('foo','bar'):  # or {'foo','bar'}: a set
For performance, store the tuple/set in a variable (whose name could be useful documentation), or just do
  if val=='foo' or val=='bar':
Conditional expression

What in CeeLanguage is written
  c ? x : y
is in Python (see for history)
  x if c else y  # note order
In Python <2.5, use (if you must) one of
  c and x or y   # incorrectly returns y if x is (any kind of) false
  (c and [x] or [y])[0]  # reliable, but ugly and churns objects
  (x, y)[not c]  # always evaluates both
  (y, x)[c]      # only if c is really a bool (or otherwise 0 or 1)


Iterating over a list
  for f in foo:
    print f * bar
  for i in range(len(foo)):
    print foo[i] * bar
Iterating over the lines in a file
  with open('foo') as f:     # automatically close f even on exception
    for line in f:
  f=file('foo')                 # synonym for open; see
  for line in f.readlines():    # store whole file in memory
In CPython, the "with" is not so necessary, as dropping the last reference to f will close the file (but that can happen later than you think in case of exceptions).

Repeat-until loop
  while True:
    if test: break



Rather than getters and setters, simply write
  class MyObj(object):
    def __init__(self):

You can later make foo a property if logic is necessary:
  class MyObj(object):
    def __init__(self): self._foo=1  # oops, it has to be odd now
    @property                   # this is a "decorator"
    def foo(self): return self._foo
    def foo(self,x): self._foo=x-x%2+1 # round up to next odd number

obj=MyObj() # now assigns 5
Dispatch tables
  disp = { 0: f0, 1: f1, 2: f2, 3: f3 } # dictionary of functions
  x=disp[n](...)                        # choose and call
  if n==0: x=f0(...)
  elif n==1: x=f1(...)
  elif n==2: x=f2(...)
  elif n==3: x=f3(...)
  else: raise KeyError(n)       # for symmetry with the above
(Python has no SwitchStatement.)


Avoid a defensive copy

If a function stores a mutable argument, you might want to copy it to avoid action at a distance:
  class A(object):
    def f(self,l): self.list=l[:]
If it's common for the call to look like
  a.f([1,2,3])  # no other reference to this list anyway
(but with a large list that shouldn't be needlessly copied) you can (in CPython) optimize away the copy:
  import sys
  class A(object):
    def f(self,l):
      if sys.getrefcount(l)>3: l=l[:]
The three allowed references are l itself, and its presence in the argument lists of f() and of getrefcount().

(This occurred to me just before writing this on June 20 2013; thoughts welcome. -- DavisHerring?)


The PythonCookbook: ISBN 0596001673 and, parts of which are written/edited by the illustrious Alex Martelli.

From Monty Python and the Holy Grail:

LAUNCELOT: No, no, sweet Concorde! Stay here! I will send help as soon as I have accomplished a daring and heroic rescue in my own particular... [sigh]
CONCORDE: Idiom, sir?

See also

CategoryPython CategoryIdiom

View edit of September 9, 2013 or FindPage with title or text search