第38集:lambda表达式
学习目标
- 理解lambda表达式的概念
- 掌握lambda表达式的基本语法
- 学会lambda表达式与普通函数的区别
- 掌握lambda在常见场景中的应用
- 理解lambda表达式的局限性
一、什么是lambda表达式?
lambda表达式是一种匿名函数,即没有名字的函数。
基本语法
lambda 参数: 表达式与普通函数的对比
| 特性 | 普通函数 | lambda表达式 |
|---|---|---|
| 定义方式 | def关键字 | lambda关键字 |
| 函数名 | 需要命名 | 无名(匿名) |
| 函数体 | 多行代码 | 单行表达式 |
| 复杂度 | 可以很复杂 | 只能写简单表达式 |
| 可读性 | 高 | 较低 |
对比示例
# 普通函数
def add(a, b):
return a + b
# lambda表达式
add_lambda = lambda a, b: a + b
# 使用方式相同
print(add(5, 3)) # 输出:8
print(add_lambda(5, 3)) # 输出:8生活类比
- 普通函数:一家正规餐厅,有招牌、菜单、服务员
- lambda表达式:路边摊,没有招牌,直接买就走
二、lambda表达式基本语法
基本形式
# 无参数
lambda: 表达式
# 一个参数
lambda x: 表达式
# 多个参数
lambda x, y, z: 表达式示例1:无参数的lambda
say_hello = lambda: "Hello, World!"
print(say_hello()) # 输出:Hello, World!
get_current_time = lambda: __import__('datetime').datetime.now()
print(get_current_time()) # 输出:当前时间示例2:单个参数的lambda
# 平方
square = lambda x: x * x
print(square(5)) # 输出:25
# 判断偶数
is_even = lambda x: x % 2 == 0
print(is_even(4)) # 输出:True
print(is_even(5)) # 输出:False
# 字符串转大写
to_upper = lambda s: s.upper()
print(to_upper("hello")) # 输出:HELLO示例3:多个参数的lambda
# 加法
add = lambda a, b: a + b
print(add(5, 3)) # 输出:8
# 三数相加
add_three = lambda a, b, c: a + b + c
print(add_three(1, 2, 3)) # 输出:6
# 计算矩形面积
area = lambda width, height: width * height
print(area(5, 3)) # 输出:15示例4:带条件表达式的lambda
# 绝对值
abs_value = lambda x: x if x >= 0 else -x
print(abs_value(5)) # 输出:5
print(abs_value(-5)) # 输出:5
# 成绩等级
grade = lambda score: "A" if score >= 90 else ("B" if score >= 80 else "C")
print(grade(95)) # 输出:A
print(grade(85)) # 输出:B
print(grade(75)) # 输出:C三、lambda表达式与内置函数
与map函数结合
# 对列表中的每个元素求平方
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x * x, numbers))
print(squared) # 输出:[1, 4, 9, 16, 25]
# 将字符串列表转大写
words = ["hello", "world", "python"]
upper_words = list(map(lambda s: s.upper(), words))
print(upper_words) # 输出:['HELLO', 'WORLD', 'PYTHON']与filter函数结合
# 筛选偶数
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # 输出:[2, 4, 6, 8, 10]
# 筛选长度大于5的字符串
words = ["apple", "banana", "pear", "orange", "kiwi"]
long_words = list(filter(lambda s: len(s) > 5, words))
print(long_words) # 输出:['banana', 'orange']与reduce函数结合
from functools import reduce
# 计算列表乘积
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
print(product) # 输出:120
# 字符串拼接
words = ["Hello", " ", "World", "!"]
sentence = reduce(lambda x, y: x + y, words)
print(sentence) # 输出:Hello World!与sorted函数结合
# 按字符串长度排序
words = ["apple", "banana", "pear", "orange", "kiwi"]
sorted_by_length = sorted(words, key=lambda s: len(s))
print(sorted_by_length) # 输出:['pear', 'kiwi', 'apple', 'banana', 'orange']
# 按绝对值排序
numbers = [3, -5, 2, -8, 1, -4]
sorted_by_abs = sorted(numbers, key=lambda x: abs(x))
print(sorted_by_abs) # 输出:[1, 2, 3, -4, -5, -8]四、lambda表达式的应用场景
场景1:排序
# 按年龄排序
students = [
{"name": "小明", "age": 18},
{"name": "小红", "age": 20},
{"name": "小华", "age": 17}
]
sorted_students = sorted(students, key=lambda x: x["age"])
print(sorted_students)
# 输出:[{'name': '小华', 'age': 17}, {'name': '小明', 'age': 18}, {'name': '小红', 'age': 20}]场景2:数据处理
# 计算列表中所有正数的平方
numbers = [1, -2, 3, -4, 5, -6]
positive_squares = [lambda x: x * x for x in numbers if x > 0] # 错误示例
# 正确方式:使用列表推导式
positive_squares = [x * x for x in numbers if x > 0]
print(positive_squares) # 输出:[1, 9, 25]
# 使用lambda和map
positive_squares = list(map(lambda x: x * x, filter(lambda x: x > 0, numbers)))
print(positive_squares) # 输出:[1, 9, 25]场景3:回调函数
# 定义一个接受函数作为参数的函数
def process_numbers(numbers, func):
"""处理数字列表"""
return [func(num) for num in numbers]
# 使用lambda作为回调
numbers = [1, 2, 3, 4, 5]
# 计算平方
squared = process_numbers(numbers, lambda x: x * x)
print(squared) # 输出:[1, 4, 9, 16, 25]
# 计算立方
cubed = process_numbers(numbers, lambda x: x ** 3)
print(cubed) # 输出:[1, 8, 27, 64, 125]场景4:事件处理
# 模拟事件处理系统
class EventManager:
def __init__(self):
self.handlers = []
def on_click(self, handler):
"""注册点击事件处理程序"""
self.handlers.append(handler)
def click(self):
"""触发点击事件"""
for handler in self.handlers:
handler()
# 创建事件管理器
manager = EventManager()
# 使用lambda注册事件处理
manager.on_click(lambda: print("按钮1被点击!"))
manager.on_click(lambda: print("按钮2被点击!"))
manager.on_click(lambda: print("按钮3被点击!"))
# 触发事件
manager.click()
# 输出:
# 按钮1被点击!
# 按钮2被点击!
# 按钮3被点击!五、lambda表达式的局限性
限制1:只能包含一个表达式
# ❌ 错误:lambda不能包含多行语句
# bad_lambda = lambda x:
# if x > 0:
# return x
# else:
# return -x
# ✅ 正确:使用条件表达式
good_lambda = lambda x: x if x > 0 else -x限制2:不能包含赋值语句
# ❌ 错误:lambda不能包含赋值
# bad_lambda = lambda x: y = x + 1
# ✅ 正确:只返回表达式
good_lambda = lambda x: x + 1限制3:不能包含print等语句
# ❌ 错误:print是语句,不是表达式
# bad_lambda = lambda x: print(x)
# ✅ 正确:如果需要print,用普通函数
def print_func(x):
print(x)限制4:可读性问题
# ❌ 复杂的lambda难以理解
complex_lambda = lambda x: (x * 2 + 1) if x > 0 else (abs(x) ** 2 - 1)
# ✅ 更好的方式:定义普通函数
def complex_func(x):
if x > 0:
return x * 2 + 1
else:
return abs(x) ** 2 - 1六、实际应用案例
案例1:学生成绩处理
# 学生成绩列表
students = [
{"name": "小明", "score": 85},
{"name": "小红", "score": 92},
{"name": "小华", "score": 78},
{"name": "小李", "score": 88}
]
# 按成绩排序
sorted_students = sorted(students, key=lambda x: x["score"], reverse=True)
print("按成绩排序:")
for student in sorted_students:
print(f" {student['name']}: {student['score']}分")
# 筛选及格学生
passing_students = list(filter(lambda x: x["score"] >= 80, students))
print("\n及格学生:")
for student in passing_students:
print(f" {student['name']}: {student['score']}分")案例2:商品价格计算
# 商品列表
products = [
{"name": "手机", "price": 2999, "discount": 0.1},
{"name": "电脑", "price": 5999, "discount": 0.15},
{"name": "耳机", "price": 199, "discount": 0.05},
{"name": "键盘", "price": 299, "discount": 0}
]
# 计算折后价格
calculate_price = lambda p: p["price"] * (1 - p["discount"])
for product in products:
final_price = calculate_price(product)
print(f"{product['name']}: 原价¥{product['price']}, 折后价¥{final_price:.2f}")案例3:数据转换
# 温度转换
celsius_to_fahrenheit = lambda c: c * 9/5 + 32
fahrenheit_to_celsius = lambda f: (f - 32) * 5/9
print("温度转换:")
print(f" 25°C = {celsius_to_fahrenheit(25):.2f}°F")
print(f" 77°F = {fahrenheit_to_celsius(77):.2f}°C")
# 货币转换
usd_to_cny = lambda usd: usd * 7.2
cny_to_usd = lambda cny: cny / 7.2
print("\n货币转换:")
print(f" $100 = ¥{usd_to_cny(100):.2f}")
print(f" ¥720 = ${cny_to_usd(720):.2f}")案例4:文本处理
# 文本处理函数
texts = [
" Hello World ",
"Python is AWESOME",
"lambda expressions",
" PROGRAMMING "
]
# 去除首尾空格并转小写
clean_text = lambda s: s.strip().lower()
cleaned_texts = list(map(clean_text, texts))
print("文本处理:")
for original, cleaned in zip(texts, cleaned_texts):
print(f" 原文:'{original}' → 处理后:'{cleaned}'")
# 提取单词首字母
first_letter = lambda s: s[0] if s else ""
words = ["apple", "banana", "cherry"]
first_letters = list(map(first_letter, words))
print(f"\n首字母:{first_letters}")七、lambda表达式的高级用法
用法1:立即执行
# 定义并立即执行lambda
result = (lambda x, y: x + y)(5, 3)
print(result) # 输出:8
# 创建并使用lambda
square = (lambda x: x * x)
print(square(5)) # 输出:25用法2:lambda返回函数
def make_multiplier(n):
"""创建乘法函数"""
return lambda x: x * n
times2 = make_multiplier(2)
times3 = make_multiplier(3)
times10 = make_multiplier(10)
print(times2(5)) # 输出:10
print(times3(5)) # 输出:15
print(times10(5)) # 输出:50用法3:lambda作为默认参数
def apply_operation(x, operation=lambda n: n * 2):
"""应用操作"""
return operation(x)
print(apply_operation(5)) # 输出:10
print(apply_operation(5, lambda n: n * 3)) # 输出:15
print(apply_operation(5, lambda n: n ** 2)) # 输出:25用法4:嵌套lambda
# 嵌套lambda
nested = lambda x: (lambda y: x + y)
add_5 = nested(5)
print(add_5(3)) # 输出:8
add_10 = nested(10)
print(add_10(3)) # 输出:13八、最佳实践
实践1:简单任务使用lambda
# ✅ 简单操作适合用lambda
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x * x, numbers))实践2:复杂逻辑使用普通函数
# ✅ 复杂逻辑用普通函数
def complex_operation(x):
"""复杂操作"""
result = x
for i in range(2, x):
result += x % i
return result
# 简单操作用lambda
numbers = [5, 10, 15]
results = list(map(complex_operation, numbers))实践3:考虑可读性
# ❌ 过于复杂的lambda
bad = lambda x: x ** 2 if x % 2 == 0 else x ** 3 if x > 0 else abs(x)
# ✅ 使用普通函数提高可读性
def transform(x):
if x % 2 == 0:
return x ** 2
elif x > 0:
return x ** 3
else:
return abs(x)实践4:为lambda赋值有意义的名字
# ✅ 有意义的变量名
is_positive = lambda x: x > 0
to_uppercase = lambda s: s.upper()
calculate_area = lambda w, h: w * h
# 使用
print(is_positive(5)) # 输出:True
print(to_uppercase("hello")) # 输出:HELLO
print(calculate_area(5, 3)) # 输出:15九、常见错误与调试
错误1:lambda包含多个表达式
# ❌ 错误
# bad = lambda x: y = x + 1; y * 2
# ✅ 正确:只使用一个表达式
good = lambda x: (x + 1) * 2错误2:lambda中缺少冒号
# ❌ 错误
# bad = lambda x x * 2
# ✅ 正确
good = lambda x: x * 2错误3:lambda中缺少return
# ❌ 错误:不需要return
# bad = lambda x: return x * 2
# ✅ 正确:lambda自动返回表达式结果
good = lambda x: x * 2调试技巧:打印lambda信息
# 查看lambda的类型
add = lambda x, y: x + y
print(type(add)) # 输出:<class 'function'>
# 查看__name__属性
print(add.__name__) # 输出:<lambda>十、小结
| 知识点 | 说明 |
|---|---|
| lambda语法 | lambda 参数: 表达式 |
| 匿名性 | 没有函数名 |
| 单行 | 只能包含一个表达式 |
| 应用场景 | map、filter、sorted等 |
| 局限性 | 不能包含语句、赋值等 |
| 建议 | 简单任务用lambda,复杂任务用函数 |
十一、课后练习
练习1
使用lambda表达式定义一个计算立方的函数。
练习2
使用lambda和filter筛选出列表中的奇数。
练习3
使用lambda和sorted按字符串长度排序。
练习4
定义一个接受lambda作为参数的函数,实现对列表的处理。
练习5
使用lambda表达式创建一个函数生成器(返回函数的函数)。