摘要
lambda
和functools.partial
在常见用例中的实际区别似乎是:
functools.partial
需要导入,而lambda
则不需要。
- 使用
functools.partial
创建的函数的函数定义可通过打印创建的函数来查看。使用lambda
创建的函数应使用inspect.getsource()
进行检查。
对于lambda
和functools.partial
,以下发现在实践中几乎相同:
速度(lambda vs functools.partial)
我认为测试和真实数据比仅仅猜测哪一个更快更有说服力。
看起来lambda
和functools.partial
之间没有速度差异的统计证据。我运行了不同数量重复的不同测试,每次结果略有不同;任何一种方法都可能最快。速度是95%(2 sigma)置信度下相同的。这里是一些数值结果*
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)
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)
回溯
我还尝试使用插入了字符串元素的列表运行f_lambda
和f_partial
,回溯(除了第一个条目)是相等的。所以在这方面没有区别。
检查源代码
- 通过打印创建的函数,可以看到使用
functools.partial
创建的函数定义。使用inspect.getsource()
应检查由lambda
创建的函数。
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)
In [3]: f_lambda
Out[3]: <function __main__.<lambda>(x)>
In [4]: inspect.getsource(f_lambda)
Out[4]: 'f_lambda = lambda x: trim_mean(x, 0.1)\n'
In [5]: inspect.getsource(f_partial)
附录
* 测试中使用的设置
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)
这些测试是在Python 3.7.3 64位版(Windows 10)上执行的。