编程Python开发者

在Python中讲讲lambda函数。与普通函数相比,它们有什么限制?在什么情况下优先使用它们,什么情况下不推荐使用?

用 Hintsage AI 助手通过面试

回答

Lambda函数是一个匿名(无名)函数,通过关键字lambda定义。通常在需要一个 "一次性" 的小函数时使用。

add = lambda x, y: x + y print(add(1, 2)) # 3

Lambda函数的限制:

  • Lambda只能包含一个表达式——也是返回值,不能进行多行计算,不能有return,条件语句类型if-else(只能以三元表达式的形式)。
  • 不能使用复杂的代码,包括try/except、循环等等。
  • Lambda不具备完整的文档(无法添加docstring)。
  • Lambda函数的可读性较差,尤其是嵌套时。

Lambda有用的情况:

  • 在单行排序/过滤键中(key参数;例如,在sortedfiltermap中)。
  • 当不需要代码重用时——局部操作,快速“插入函数”。

何时最好避免使用Lambda:

  • 在复杂的逻辑中:为了重复使用、大量代码或条件,为了可理解性和可读性,最好提取到带名称和docstring的def函数中。

反向提问

问题: Lambda函数能否使用外部作用域中的变量,这对它们在循环内的工作有什么影响?

回答: Lambda函数可以捕获外部上下文中的变量(词法闭包)。当在循环内定义时,这通常会导致意外行为——Lambda在调用时使用的是变量的当前值,而不是“定义时的值”。

funcs = [] for i in range(3): funcs.append(lambda: i) # 所有函数将返回2(循环后i=2) print([f() for f in funcs]) # [2, 2, 2]

要捕获"旧"值:

funcs = [] for i in range(3): funcs.append(lambda i=i: i) print([f() for f in funcs]) # [0, 1, 2]

由于对主题细微之处的不理解而导致的实际错误示例


故事

在一个项目中使用Lambda根据特定键过滤字典列表。循环内的Lambda捕获了在调用时有不同(意外)值的变量。结果——过滤不正确,报告出现错误。


故事

在一个大的Django项目中:复杂的验证表单,实现为长表达式在Lambda函数内。后来业务逻辑发生了变化,Lambda无法容纳所有代码,必须重写为普通函数。Lambda减缓了调试过程。


故事

在一个初创公司中,不成功地使用Lambda传递排序函数,忘记它返回错误的类型(例如,不是元组,而是列表)。这导致不可预测的排序和数据去重中的错误。