lambda 匿名函数
·
lambda:创建轻量匿名小函数,只能写单个表达式,不能写多行、不能写if语句块、for循环,表达式的结果自动作为返回值,不用写return。
基础语法
lambda 参数1,参数2 : 表达式
示例:
add = lambda a,b : a + b
print(add(2,3)) # 5
等价普通函数:
def add(a,b):
return a + b
常用场景:配合sorted、map、filter
data = [("apple",3),("banana",1),("orange",2)]
# 按元组第二个元素排序
res = sorted(data, key=lambda x: x[1])
print(res)
nums = [1,2,3]
res = list(map(lambda x:x*2, nums))
print(res) # [2,4,6]
⚠️lambda经典大坑:延迟绑定(面试高频)
funcs = []
for i in range(3):
funcs.append(lambda : print(i))
for f in funcs:
f()
# 输出:
# 2
# 2
# 2
不是输出0,1,2;lambda捕获的是变量i本身,不是当时i的值;循环结束i=2,全部lambda执行的时候都拿最后i=2。
修复:给lambda增加默认参数,立刻捕获当时的值
funcs = []
for i in range(3):
funcs.append(lambda val=i : print(val))
for f in funcs:
f()
# 0 1 2
lambda 和闭包、刚才的UnboundLocalError关联
lambda内部赋值依然会触发局部变量规则,lambda里面不能做赋值语句,只能表达式。
# ❌ 错误,lambda内部不能写 cnt[0] +=1 这种赋值语句,这是语句不是表达式
bad = lambda : cnt[0] +=1
+=是赋值statement,lambda主体只能是expression,所以这种逻辑不能写lambda。
lambda 能不能用三元表达式(可以)
三元运算符是表达式,可以放lambda:
f = lambda x: x if x>0 else -x
print(f(-5)) #5
不推荐使用场景
- lambda逻辑复杂,三元套三元,可读性变差,直接换成def普通函数;
- 回调函数里面写很长的lambda,调试堆栈不好看;
速记
- lambda是匿名函数,只能单个表达式,隐式return,不能写多行代码块。
- 循环生成lambda要警惕延迟捕获变量,用默认参数
val=i修复。 - 不能在lambda里面写赋值语句
+=。 - 多用于
sorted key、map、filter简短回调。
对比nonlocal / lambda小例子
def outer():
cnt = [0]
inc = lambda : (cnt.__setitem__(0, cnt[0]+1), cnt[0])[1]
print(inc())
print(inc())
outer()
# 输出1,2;只是演示,工程不要这么写,可读性极差,直接def函数。
工程实际:不要强行把多行逻辑塞进lambda,普通def优先。
更多推荐

所有评论(0)