python函数分Lambda匿名函数与def普通函数,除此之外,还有三元表达式。
三者的极简选择规定:
- 仅单行赋值,不需要封装函数 → 三元表达式
- 单行逻辑、只用一次、临时回调 → lambda
- 多行逻辑、多处复用、需要注释/异常处理 → def函数
一、先理清三者从属关系
-
三元表达式 :是表达式语法 (用来快速实现if-else选择),不是函数;可以单独使用,也能写在lambda内部。
python# 语法:真值 if 条件 else 假值 result = a if a > 0 else 0 -
lambda :构建简易匿名函数 ;
:后面只能放一条表达式(这条表达式可以是三元表达式、算术运算等)。 -
def :定义具名正式函数,可以编写多行语句、循环、if块、异常捕获。
二、三者能力对比表
| 特性 | 三元表达式 | lambda 匿名函数 | def 普通函数 |
|---|---|---|---|
| 是否函数 | ❌ 只是表达式,不能直接传参调用 | ✅ 函数(匿名) | ✅ 函数(有名字) |
| 代码行数 | 单行,只能表达式 | 单行,仅支持一条表达式 | 支持任意多行代码 |
| 分支写法 | 仅支持单层/嵌套三元 | 内部只能嵌套三元表达式,不能写if:代码块 |
支持完整if/elif/else、for循环、try异常 |
| 能否复用 | 不能单独作为函数传入 | 只能临时一次性使用;无法多处调用、不好调试 | 可在整个程序任意位置多次调用 |
| 支持return | ❌ | ❌ 自动返回表达式结果 | ✅ 显式return |
| 添加注释 | ❌ 无法书写文档注释 | ❌ 不能写多行文档注释 | ✅ 支持文档字符串 """注释""" |
示例直观区分
python
x = 5
# 三元表达式(独立使用)
res = np.log1p(x) if x > 0 else 0
# lambda 内部使用三元表达式
func = lambda u: np.log1p(float(u)) if float(u) > 0 else 0
# def函数,自由书写完整逻辑
def sales_transform(u):
"""销量对数转换函数"""
try:
val = float(u)
if val > 0:
return np.log1p(val)
else:
return 0
except ValueError:
# 可以捕获异常,lambda做不到
return 0
三、明确使用边界(什么时候选谁,工程规范)
场景1:只用【三元表达式】
需求:不需要封装成函数,只是在一行内快速二选一赋值
适用:简单赋值
python
# 例子:对单个数值进行转换
sales = 10
log_sales = np.log1p(sales) if sales > 0 else 0
❌ 不要强行套lambda:没必要为一行赋值单独创建函数
场景2:选用【lambda】
满足全部3个条件再使用lambda:
- 逻辑极度简短(一条表达式);
- 函数只使用一次(回调、map/apply、sorted、read_csv converters);
- 不需要异常捕获、不需要写注释文档。
典型例子:
python
# 和你代码完全一致,一次性传入,用完即弃
pd.read_csv(path, converters={'unit_sales': lambda u: ...})
# sorted排序临时规则
data.sort(key=lambda x: x[1])
❌ lambda禁止场景
- 逻辑复杂,需要多层判断;
- 需要异常捕获;
- 同一个函数需要在代码中多处调用;
- 需要写注释说明功能(模型项目、正式工程代码)。
刷题可以随便写lambda;上线工程代码不推荐长lambda!
场景3:选用【def 普通函数】
满足任意一条,优先使用def:
- 逻辑超过一行,需要循环、完整if分支、try-except异常处理;
- 函数会在脚本多个地方重复调用;
- 需要添加文档注释、参数说明,方便他人阅读;
- 需要调试、打印中间变量;
正式项目推荐def写法:
python
def transform_unit_sales(raw_value):
"""
对原始销量进行log1p转换
param raw_value: csv读取的原始销量字符串
return: 对数变换后销量,销量≤0返回0
"""
try:
val = float(raw_value)
return np.log1p(val) if val > 0 else 0
except ValueError:
# 如果csv存在脏数据、空字符串,不会直接崩溃
return 0
# 调用
pd.read_csv(path, converters={'unit_sales': transform_unit_sales})
四、易错误区
误区1:三元表达式 == lambda
错。
三元表达式是运算逻辑 ;lambda是函数容器。
python
# 三元表达式(直接算出结果)
a = 10 if 5>0 else 0
# lambda(得到一个函数对象,必须调用才能计算)
f = lambda : 10 if 5>0 else 0
a = f()
误区2:lambda里面可以写if代码块
❌ 错误写法,直接报语法错误
python
lambda u:
val = float(u)
if val>0:
return np.log1p(val)
else:
return 0
lambda冒号后只能写表达式,不能写语句块。想要多行逻辑只能用def。
误区3:牛人代码常用lambda,工程代码照搬照抄
Kaggle竞赛追求代码简短快速实验,大量lambda;
但工业项目要求可维护、容错、易阅读,应尽量减少lambda。