Recently there was a thread about function composition in Python (and this was probably not the first). The fast way to create a (anonymous) composite function
f1 o f2 o ... o fnin Python is via
lambda x: f1(f2(...fn(x)...)),compose function such that the above can
be written
compose(f1, f2, ...., fn),getcomposer is a helper function (which in most
cases will amount to a dictionary lookup).
This is how it works
>>> def succ(x): return x+1 ... >>> def double(x): return 2*x ... >>> def square(x): return x**2 ... >>> def succ(x): return x+1 ... >>> f1 = compose(double, square, succ, float) >>> f1(8)162.0>>>
Here is a benchmark for speed against the traditional
lambda method for composing functions.  It shows that
using compose incurs no speed penalty.
>>> f2 = lambda x: double(square(succ(float(x)))) >>> >>> def benchmark(f, n=1000000): ... from time import time ... t0 = time() ... for x in xrange(n): f(x) ... t1 = time() ... return t1-t0 ... >>> print 'compose', benchmark(f1)compose 1.83817005157>>> print 'lambda ', benchmark(f2)lambda 1.99733304977>>>
Looking at the bytecode for f1 and f2:
>>> import dis >>> dis.dis(f1)1 0 LOAD_DEREF 0 (f0) 3 LOAD_DEREF 3 (f1) 6 LOAD_DEREF 1 (f2) 9 LOAD_DEREF 2 (f3) 12 LOAD_FAST 0 (x) 15 CALL_FUNCTION 1 18 CALL_FUNCTION 1 21 CALL_FUNCTION 1 24 CALL_FUNCTION 1 27 RETURN_VALUE>>> dis.dis(f2)23 0 LOAD_GLOBAL 0 (double) 3 LOAD_GLOBAL 1 (square) 6 LOAD_GLOBAL 2 (succ) 9 LOAD_GLOBAL 3 (float) 12 LOAD_FAST 0 (x) 15 CALL_FUNCTION 1 18 CALL_FUNCTION 1 21 CALL_FUNCTION 1 24 CALL_FUNCTION 1 27 RETURN_VALUE>>>
f1 and f2 are almost exaclty the same but
array lookups (LOAD_DEREFs) in f1 replace dictionary
lookups (LOAD_GLOBALs) in f2.  A C version of
compose could easily be written that doesn't the use of a
python lambda-function (as created by getcomposer).