Python3 lambda
匿名函数的语法、与 def 的取舍、配合 map/filter/sorted 使用及常见陷阱。
lambda 语法
lambda args: expr creates an anonymous function whose value is the expression — no return needed. It is still a function object: assignable and immediately callable.
f = lambda x: x + 1
print(f(1), type(f).__name__)
print((lambda x, y: x * y)(3, 4))
print((lambda: "no args")())
add = lambda *args: sum(args)
print(add(1, 2, 3))2 function
12
no args
6lambda 与 def 的对比
def allows multiple statements, docstrings and a real name in debuggers; a lambda is a single anonymous expression. Use a lambda only when the body is one expression and the function is throwaway.
def square_def(x):
"""返回平方"""
return x * x
square_lambda = lambda x: x * x
print(square_def(3), square_lambda(3))
print(square_def.__name__, square_lambda.__name__)
print(bool(square_def.__doc__), square_lambda.__doc__)9 9
square_def <lambda>
True None配合 map/filter/sorted 使用
Lambdas shine as throwaway rules for higher-order functions: sorted(key=...), map for transforms, filter for selection, max/min(key=...) for extremes by field.
rows = [('b', 2), ('a', 3), ('c', 1)]
print(sorted(rows, key=lambda r: r[1]))
print(sorted(rows, key=lambda r: r[0], reverse=True))
print(list(map(lambda r: r[0].upper(), rows)))
print(list(filter(lambda r: r[1] > 1, rows)))
print(max(rows, key=lambda r: r[1]))[('c', 1), ('b', 2), ('a', 3)]
[('c', 1), ('b', 2), ('a', 3)]
['B', 'A', 'C']
[('b', 2), ('a', 3)]
('a', 3)闭包与默认参数陷阱
A lambda captures the *variable*, not the value. Lambdas created in a loop share the loop variable and all see its final value — bind the current value with a default argument like x=x.
fs = [lambda: i for i in range(3)]
print([f() for f in fs])
fs2 = [lambda i=i: i for i in range(3)]
print([f() for f in fs2])
def make_adder(n):
return lambda x: x + n
add5 = make_adder(5)
print(add5(10), add5(0))[2, 2, 2]
[0, 1, 2]
15 5def defaults: def f(x, acc=[]) shares one list across calls. Use acc=None and create it inside.lambda 语法
lambda 参数: 表达式 创建匿名函数,表达式的值就是返回值,不需要 return。它本质仍是函数对象,可以赋值、可以立即调用。
f = lambda x: x + 1
print(f(1), type(f).__name__)
print((lambda x, y: x * y)(3, 4))
print((lambda: "no args")())
add = lambda *args: sum(args)
print(add(1, 2, 3))2 function
12
no args
6lambda 与 def 的对比
def 能写多行、能写文档字符串、能在调试器里显示名字;lambda 只有一行、没有名字。只在函数体是一个表达式、且用完就丢时才用 lambda。
def square_def(x):
"""返回平方"""
return x * x
square_lambda = lambda x: x * x
print(square_def(3), square_lambda(3))
print(square_def.__name__, square_lambda.__name__)
print(bool(square_def.__doc__), square_lambda.__doc__)9 9
square_def <lambda>
True None配合 map/filter/sorted 使用
lambda 最实用的场景是给高阶函数传一次性规则:sorted(key=...) 按字段排序、map 做逐元素变换、filter 做筛选、max/min(key=...) 按字段取极值。
rows = [('b', 2), ('a', 3), ('c', 1)]
print(sorted(rows, key=lambda r: r[1]))
print(sorted(rows, key=lambda r: r[0], reverse=True))
print(list(map(lambda r: r[0].upper(), rows)))
print(list(filter(lambda r: r[1] > 1, rows)))
print(max(rows, key=lambda r: r[1]))[('c', 1), ('b', 2), ('a', 3)]
[('c', 1), ('b', 2), ('a', 3)]
['B', 'A', 'C']
[('b', 2), ('a', 3)]
('a', 3)闭包与默认参数陷阱
lambda 捕获的是变量而不是值。在循环里创建多个 lambda 时,它们共享同一个循环变量,全部指向最终值 —— 用默认参数 x=x 可以把当前值绑死。
fs = [lambda: i for i in range(3)]
print([f() for f in fs])
fs2 = [lambda i=i: i for i in range(3)]
print([f() for f in fs2])
def make_adder(n):
return lambda x: x + n
add5 = make_adder(5)
print(add5(10), add5(0))[2, 2, 2]
[0, 1, 2]
15 5def 的默认参数上:def f(x, acc=[]) 会让所有调用共享同一个列表。改用 acc=None 再在函数内创建。