《Python3.8.5
文档》笔记:函数式编程之lambda
表达式
编写函数式风格程序时,我们经常会需要很小的函数作为谓词函数或者以某种方式来组合元素。
如果存在合适的Python
内置的或者其他模块中的函数,就一点也不需要定义新的函数,例如:
stripped_lines = [line.strip() for line in lines]
existing_files = filter(os.path.exists, file_list)
如果不存在我们需要的函数,就必须自己编写。一种编写小函数的方式是使用lambda
表达式。lambda
接受一组参数以及组合这些参数的表达式,它会创建一个返回表达式值的匿名函数:
adder = lambda x, y: x+y
print_assign = lambda name, value: name + '=' + str(value)
另一种替代方案就是通常的使用def
语句来定义函数:
def adder(x, y):
return x + y
def print_assign(name, value):
return name + '=' + str(value)
哪一种风格更受青睐呢?这是一个风格问题:通常的做法是避免使用lambda
。
如此偏好的一个原因是lambda
能够定义的函数非常受限。函数的结果必须能够作为单独的表达式来计算,这意味着你不能使用多路if...elif...else
比较,或者try...except
语句。如果你尝试在lambda
语句中做太多事情,你最终会把表达式写得过于复杂以至于难以阅读。例如下面的代码,你能快速看出这段代码做了什么事情吗?
import functools
total = functools.reduce(lambda a, b: (0, a[1] + b[1]), items)[1]
而这种情况下,使用一个简短的嵌套的def
语句看起来会好一点:
import functools
def combine(a, b):
return 0, a[1] + b[1]
total = functools.reduce(combine, items)[1]
如果仅仅使用一个for
循环会更好:
total = 0
for a, b in items:
total += b
或者使用内置的sum()
和一个生成器表达式:
total = sum(b for a, b in items)
许多使用functools.reduce()
的情形可以更清晰地写成for
循环的形式。
Python
资深人士、《Python
标准库》的作者Fredrik Lundh
曾经建议以下一组规则来重构lambda
的使用:
- 写一个
lambda
函数 - 写一句注释来说明这个
lambda
究竟干了什么 - 研究一会这个注释,然后想出一个抓住注释本质的名字
- 用这个名字,然后把这个
lambda
改成def
语句 - 把注释去掉