目录
2.3 reduce(func, iterable[, initializer])
2.4 sorted(iterable, key=None, reverse=False)
2.5 any(iterable) 和 all(iterable)
2.6. max(iterable, key=func) 和 min(iterable, key=func)
4.2 nonlocal: 修改外层非全局变量(通常用于闭包)
一、匿名函数
lambda 是实现匿名函数的语法,匿名函数是 lambda 的核心用途。
匿名函数(Anonymous Function)是指没有名字的函数,它们的设计初衷是为了在需要临时函数对象的场合使用。Python 中通过 lambda 表达式来定义匿名函数,因此:
lambda 表达式就是 Python 中创建匿名函数的唯一方式。
1、匿名函数 vs 普通函数
| 特性 | 普通函数(def) | 匿名函数(lambda) |
|---|---|---|
| 是否有函数名 | 有(例如:def foo():) | 没有,用变量绑定或直接使用 |
| 写法复杂度 | 可以写多行语句 | 只能写一行表达式 |
| 功能复杂度 | 可包含任意逻辑、条件、循环等 | 仅限简单表达式 |
| 是否推荐长期使用 | 是,用于复用和清晰代码结构 | 否,适用于临时使用场景 |
2、lambda 是匿名函数的实现方式
语法回顾:
lambda 参数1, 参数2, ... : 表达式
这个表达式的值就是函数的返回值。
举例:
# 普通函数定义
def multiply(x, y):
return x * y
# 匿名函数定义(lambda)
multiply_lambda = lambda x, y: x * y
# 调用比较
print(multiply(3, 4)) # 输出: 12
print(multiply_lambda(3, 4)) # 输出: 12
注意:lambda 定义的是匿名函数本体,而不是执行调用。 你可以把这个函数赋值给一个变量,也可以直接作为参数传入函数(更常见)。
3、lambda 的常见用途(匿名函数的典型使用)
匿名函数适用于那些你不想给函数起名,且只使用一次的场景,例如:
排序:
data = [(1, 2), (3, 1), (5, 0)]
sorted_data = sorted(data, key=lambda x: x[1])
# 按照第二个元素排序
map():对序列进行转换
nums = [1, 2, 3]
squares = list(map(lambda x: x**2, nums))
filter():条件筛选
nums = [1, 2, 3, 4]
even = list(filter(lambda x: x % 2 == 0, nums))
reduce():累积操作(需导入)
from functools import reduce
result = reduce(lambda x, y: x + y, [1, 2, 3, 4])
4、匿名函数的特点与局限总结
✅ 优点:
简洁、写法短;
避免定义额外函数名;
用于函数式编程、事件处理、回调、临时操作等场景很方便。
❌ 局限:
只能写单个表达式,不能写多行语句;
不支持复杂的控制结构(如
if-else多分支、for循环);调试困难,不利于代码复用和维护;
无法使用注释、函数文档(docstring)等功能。
二、高阶函数
1. 什么是高阶函数
在 Python 中,函数是一等对象,可以像变量一样传递、赋值、作为返回值。
因此,高阶函数是指满足以下任意一个条件的函数:
将函数作为参数传入
返回一个函数
示例:
def apply(func, x):
return func(x)
def square(n):
return n * n
print(apply(square, 5)) # 输出 25
上述 apply 就是一个高阶函数,它接受另一个函数 func 作为参数。
2. Python 内置的常见高阶函数
以下为 Python 中最常用的高阶函数及其使用方式:
2.1 map(func, iterable)
对可迭代对象的每个元素应用函数,并返回一个新的迭代器。
nums = [1, 2, 3, 4]
squares = list(map(lambda x: x ** 2, nums))
# 输出: [1, 4, 9, 16]
2.2 filter(func, iterable)
筛选可迭代对象中使 func(x) 返回 True 的元素。
nums = [1, 2, 3, 4, 5]
evens = list(filter(lambda x: x % 2 == 0, nums))
# 输出: [2, 4]
2.3 reduce(func, iterable[, initializer])
需要引入 functools 模块,用于连续将 func 应用于序列(从左至右),把结果累积起来。
from functools import reduce
nums = [1, 2, 3, 4]
product = reduce(lambda x, y: x * y, nums)
# 输出: 24
2.4 sorted(iterable, key=None, reverse=False)
带 key 参数的排序函数,key 接收一个函数用于提取排序依据。
words = ["banana", "apple", "pear"]
sorted_words = sorted(words, key=lambda x: len(x))
# 输出: ['pear', 'apple', 'banana']
2.5 any(iterable) 和 all(iterable)
虽然不是典型的接受函数参数,但常配合生成器表达式一起用,逻辑上仍具有高阶特性。
nums = [0, 1, 2]
print(any(x > 1 for x in nums)) # True
print(all(x >= 0 for x in nums)) # True
2.6. max(iterable, key=func) 和 min(iterable, key=func)
也可接收函数作为 key 参数,用于提取比较依据。
students = [{"name": "Alice", "score": 88}, {"name": "Bob", "score": 95}]
best = max(students, key=lambda s: s["score"])
# 输出: {'name': 'Bob', 'score': 95}
大家可以查看python官方文档查看更多的函数使用方法:
3. 自定义高阶函数的典型场景
3.1 函数作为参数传入
def operate(x, y, func):
return func(x, y)
result = operate(3, 5, lambda a, b: a + b)
# 输出: 8
3.2 函数作为返回值返回
这就是闭包(closure)的一种表现形式。
def make_multiplier(n):
def multiplier(x):
return x * n
return multiplier
times3 = make_multiplier(3)
print(times3(4)) # 输出: 12
我们在下一篇文章会详细介绍闭包的相关知识。
4. 总结:高阶函数的优点
增强代码的通用性和抽象能力
配合 lambda 表达式、推导式使代码更简洁
适合用于数据处理、管道处理、函数组合等场景
是理解装饰器、闭包、函数式编程的基础
5. 常用高阶函数功能速查表
| 函数名 | 功能描述 | 是否返回迭代器 |
|---|---|---|
map | 对每个元素应用函数 | 是 |
filter | 保留使函数返回 True 的元素 | 是 |
reduce | 将函数连续应用于序列 | 否 |
sorted | 可基于函数排序 | 否 |
max/min | 使用函数提取比较依据 | 否 |
any/all | 结合生成器表达式检查逻辑 | 否 |
三、匿名函数lambda与高阶函数的混合使用
1. map() + lambda
对序列中每个元素执行某种转换
nums = [1, 2, 3]
doubled = list(map(lambda x: x * 2, nums))
print(doubled) # [2, 4, 6]
2. filter() + lambda
筛选符合条件的元素
nums = [1, 2, 3, 4, 5]
even = list(filter(lambda x: x % 2 == 0, nums))
print(even) # [2, 4]
3. sorted() + lambda
根据某个规则排序
students = [('Tom', 88), ('Jerry', 95), ('Anna', 72)]
# 按成绩排序
sorted_students = sorted(students, key=lambda x: x[1])
print(sorted_students)
4. reduce() + lambda (需导入)
from functools import reduce
nums = [1, 2, 3, 4]
product = reduce(lambda x, y: x * y, nums)
print(product) # 24
5. lambda + 自定义高阶函数
你也可以自己写高阶函数,然后把 lambda 传进去:
def apply_twice(func, value):
return func(func(value))
result = apply_twice(lambda x: x + 3, 4)
print(result) # ((4 + 3) + 3) = 10
综合案例:学生成绩处理
import random
students = ['Alice', 'Bob', 'Charlie']
scores = [{'name': s, 'score': random.randint(50, 100)} for s in students]
# 过滤出成绩大于 60 的
passed = list(filter(lambda x: x['score'] >= 60, scores))
# 按成绩排序
sorted_passed = sorted(passed, key=lambda x: x['score'], reverse=True)
# 取出名字列表
names = list(map(lambda x: x['name'], sorted_passed))
print("及格学生:", names)
四、变量作用域
1. 什么是变量作用域?
变量作用域:变量在程序中可见和可用的范围。
Python 中有 4 种作用域(记作 LEGB):
| 缩写 | 名称 | 说明 |
|---|---|---|
| L | Local | 函数内部定义的局部变量 |
| E | Enclosing | 嵌套函数的外部函数中的变量(闭包相关) |
| G | Global | 模块级别定义的变量(全局变量) |
| B | Built-in | Python 解释器预定义的内置变量(如 len) |
2.LEGB 查找顺序(变量解析规则)
当你在函数中访问一个变量时,Python 会按照 LEGB 的顺序查找:
Local -> Enclosing -> Global -> Built-in
一旦在某一层找到了这个变量,就不再继续向外查找。
示例讲解:LEGB 顺序
x = "global" # Global
def outer():
x = "enclosing" # Enclosing
def inner():
x = "local" # Local
print(x)
inner()
outer()
# 输出:local
如果我们注释掉
x = "local",它就会打印enclosing,依此类推。
3. 内置作用域示例(Built-in)
print(len("hello")) # len 是内置函数
如果你不小心写了:
len = 10
print(len("abc")) # ❌ 会报错,因为 len 被你覆盖成了变量!
所以不要随意覆盖内置变量名!
4.global 和 nonlocal 关键词的作用
4.1 global: 修改全局变量
x = 5
def change_global():
global x
x = 10
change_global()
print(x) # 输出 10
4.2 nonlocal: 修改外层非全局变量(通常用于闭包)
def outer():
x = 5
def inner():
nonlocal x
x = 10
inner()
print(x)
outer() # 输出 10
5. 变量作用域表格
| 类型 | 定义在哪 | 是否能在函数中访问 | 是否能修改(默认) |
|---|---|---|---|
| Local | 函数内部 | ✅ | ✅ |
| Enclosing | 外层嵌套函数 | ✅(闭包) | nonlocal 才能修改 |
| Global | 模块最外层 | ✅ | global 才能修改 |
| Built-in | Python 自带 | ✅ | ❌(不可改) |
五、递归函数
1.概念
递归是指函数直接或间接调用自身的过程。递归通常用于解决分解成相似子问题的复杂问题。
1.1 函数结构
递归函数通常由两个部分组成:
-
终止条件:用于确保递归能够停止,避免无限递归。
-
递归调用:函数在其内部调用自身,传递简化或减少的参数,以解决更小的子问题。
1.2 基本步骤
-
定义递归函数:在函数体内调用函数自身。
-
设定终止条件:确保递归能终止。
-
逐步简化问题:通过传递较小的参数递归求解,直至终止条件满足。
1.3 递归示例
递归:先递进,再回归。
1.3.1 阶乘定义
-
n! = n * (n-1) * (n-2) * ... * 1 -
递归公式:
n! = n * (n-1)!,终止条件:0! = 1
示例代码:
def factorial(n):
# 终止条件:n为0或1时,返回1
if n == 0 or n == 1:
return 1
# 递归调用:n * (n-1)!
return n * factorial(n - 1)
# 测试
print(factorial(6)) # 输出 720
1.3.2 斐波那契数列
斐波那契数列(Fibonacci sequence)是一种经典的数列,它的特点是从第 3 项开始,每一项都等于前两项之和。前两项通常定义为:
F(0) = 0
F(1) = 1
从 F(2) 开始:
F(2) = F(1) + F(0) = 1 + 0 = 1
F(3) = F(2) + F(1) = 1 + 1 = 2
使用递归的思想实现斐波那契数列
参考代码:
def fb(n):
if n == 0 or n == 1:
return n
return fb(n - 1) + fb(n - 2)
递归数列的关键是找到边界墙!
2.怎么找 "边界墙" ?
2.1 什么是“边界墙”?
“边界墙”就是:
不再继续递归的条件
让递归有机会返回、不陷入无限调用
你可以把递归想成一口井,你不断往下跳(每次递归),但你得知道什么时候到底了(边界墙),不然你永远掉下去。
一句话:边界墙就是终止条件;
作用是避免无限递归,保证能返回结果;
通常写在递归函数的最前面。
2.2 找边界墙的两个关键思维
-
找最简单、最小的情况 通常是:
n=0或n=1,这时候你不需要再递归,可以直接返回结果。 -
问自己:什么时候我可以不再递归?
例子1:阶乘(n!)
def factorial(n):
if n == 1: # ⬅️ 这是边界墙
return 1
return n * factorial(n - 1)
-
递归思路:
n! = n * (n-1)! -
边界墙是
n == 1,不能一直减,否则无限递归。
例子2:斐波那契数列
def fib(n):
if n == 0 or n == 1: # ⬅️ 这是边界墙
return n
return fib(n - 1) + fib(n - 2)
-
fib(0)和fib(1)是基本情况,不再递归。 -
从这里开始“往上回溯”,组合出更大的 fib。
例子3:递归打印列表元素
def print_list(lst, i=0):
if i >= len(lst): # ⬅️ 边界墙:到头了
return
print(lst[i])
print_list(lst, i + 1)
-
最简单情况是:
i >= len(lst),表示没东西可打印了,停止递归。
通用模板(找边界墙)
def recursive(参数):
if 满足终止条件: # ⬅️ 这是边界墙
return 最简单情况结果
else:
return recursive(更接近终止条件的参数)
记忆口诀:递归三部曲(写的时候就像搭框架)
| 步骤 | 要做的事 | 举例 |
|---|---|---|
| 第1步 | 写终止条件(边界墙) | if n == 1: return 1 |
| 第2步 | 写递归逻辑(缩小规模) | factorial(n-1) |
| 第3步 | 返回本层结果 + 递归结果 | return n * factorial(n-1) |
2182

被折叠的 条评论
为什么被折叠?



