Idioms for PythonLanguage.
Expressions
Multiple assignment
def find_best(key): ... return new_key, value key, value = find_best(key) a, b = b, a # swapInterval test
if 2 < x < 4: print "x is between 2 and 4."Set membership test
if val in ('foo','bar'): # or {'foo','bar'}: a setFor 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 : yis in Python (see http://www.python.org/peps/pep-0308.html for history)
x if c else y # note orderIn 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)
Loops
Iterating over a list
for f in foo: print f * barnot
for i in range(len(foo)): print foo[i] * barIterating over the lines in a file
with open('foo') as f: # automatically close f even on exception for line in f: ...not
f=file('foo') # synonym for open; see http://mail.python.org/pipermail/python-dev/2004-July/045921.html 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 ...
Functions
Properties
Rather than getters and setters, simply write
class MyObj(object): def __init__(self): self.foo=0 obj=MyObj() obj.foo=4You 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 @foo.setter def foo(self,x): self._foo=x-x%2+1 # round up to next odd number obj=MyObj() obj.foo=4 # now assigns 5Dispatch tables
disp = { 0: f0, 1: f1, 2: f2, 3: f3 } # dictionary of functions x=disp[n](...) # choose and callnot
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.)
Optimization
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=A() 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[:] self.list=lThe 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?)
Others
The PythonCookbook: ISBN 0596001673 and http://aspn.activestate.com/ASPN/Cookbook/Python/, parts of which are written/edited by the illustrious Alex Martelli.
From Monty Python and the Holy Grail: