Summary
The practical differences between lambda
and functools.partial
in the common use cases seems to be
functools.partial
needs an import, lambda
does not.
- The function definition for functions created with
functools.partial
is visible just by printing the created function. The functions created with lambda
should be inspected with inspect.getsource()
.
These were found to be practically identical for lambda
and functools.partial
Speed (lambda vs functools.partial)
I think that tests and real data speaks louder than just guesses about which one is faster than the another.
Looks like that there is no statistical proof for speed difference between lambda
and functools.partial
. I ran different tests with different amount of repetitions, getting slightly different results each time; any of the three approaches could be the fastest. The speeds were identical with 95% (2 sigma) confidence. Here are some numerical results*
# When functions are defined beforehand
In [1]: timeit -n 1000 -r 1000 f_partial(data)
23.6 µs ± 2.92 µs per loop (mean ± std. dev. of 1000 runs, 1000 loops each)
In [2]: timeit -n 1000 -r 1000 f_lambda(data)
22.6 µs ± 2.6 µs per loop (mean ± std. dev. of 1000 runs, 1000 loops each)
# When function is defined each time again
In [3]: timeit -n 1000 -r 1000 (lambda x: trim_mean(x, 0.1))(data)
22.6 µs ± 1.98 µs per loop (mean ± std. dev. of 1000 runs, 1000 loops each)
In [4]: timeit -n 1000 -r 1000 f_lambda = lambda x: trim_mean(x, 0.1); f_lambda(data)
23.7 µs ± 3.89 µs per loop (mean ± std. dev. of 1000 runs, 1000 loops each)
In [5]: timeit -n 1000 -r 1000 f_partial = partial(trim_mean, proportiontocut=0.1); f_partial(data)
24 µs ± 3.38 µs per loop (mean ± std. dev. of 1000 runs, 1000 loops each)
Tracebacks
I also tried running the f_lambda
and f_partial
using list with string element inserted, and the tracebacks were equal (except for the very first entry, of course). So there is no difference there.
Inspecting the source code
- The function definition for functions created with
functools.partial
is visible just by printing the created function. The functions created with lambda
should be inspected with inspect.getsource()
.
# Can be inspected with just printing the function
In [1]: f_partial
Out[1]: functools.partial(<function trim_mean at 0x000001463262D0D0>, proportiontocut=0.1)
In [2]: print(f_partial)
functools.partial(<function trim_mean at 0x000001463262D0D0>, proportiontocut=0.1)
# Lambda functions do not show the source directly
In [3]: f_lambda
Out[3]: <function __main__.<lambda>(x)>
# But you can use inspect.getsource()
In [4]: inspect.getsource(f_lambda)
Out[4]: 'f_lambda = lambda x: trim_mean(x, 0.1)\n'
# This throws a ValueError, though.
In [5]: inspect.getsource(f_partial)
Appendix
* Setup used in the tests
from functools import partial
from scipy.stats import trim_mean
import numpy as np
data = np.hstack((np.random.random(1000), np.random.random(50)*25000))
f_lambda = lambda x: trim_mean(x, 0.1)
f_partial = partial(trim_mean, proportiontocut=0.1)
The tests were performed on Python 3.7.3 64-bit (Windows 10).