Python 函数进阶全解|作用域 global/nonlocal、lambda 匿名函数、高阶函数 map/filter/reduce、递归函数实战
文章目录
一、前言
Python 函数是编程核心基础,入门只懂简单 def 远远不够。实际开发高频用到变量作用域、global/nonlocal、lambda 匿名函数、四大内置高阶函数、递归五大知识点,也是面试高频考点。本文结合完整可运行代码,一次性梳理全部核心用法,零基础也能看懂。
二、变量作用域:global 与 nonlocal 关键字详解
2.1 作用域基础规则
全局作用域:文件最外层定义的变量,所有函数均可读取;
局部作用域:函数内部定义变量,仅当前函数可用;
嵌套作用域:函数内部再定义函数,内层可读取外层函数变量,直接赋值会新建局部变量。
关键坑点
仅读取外部变量,无需任何关键字;
给外部变量重新赋值,默认创建局部变量,不会修改外部;
可变对象(list/dict)调用方法修改内部数据(append/pop),不用关键字即可改动外部容器。
示例 1:不赋值仅修改列表内容
a = 20
datas = [1,2,3]
def f2():
# 无赋值语句,仅调用方法修改列表,直接改动全局datas
datas.append(4)
f2()
print(a, datas) # 输出:20 [1, 2, 3, 4]
示例 2:函数内直接赋值,生成局部变量,全局不变
a = 20
datas = [1,2,3]
def f2():
datas = ["a","b","c"] # 新建局部变量,不影响全局
f2()
print(a, datas) # 输出:20 [1, 2, 3]
2.2 global 关键字:修改全局变量
适用场景:任意函数内部,想要修改文件最外层全局变量。
语法:global 变量1,变量2,声明后赋值操作作用于全局。
a = 20
datas = [1,2,3]
def f2():
global a, datas # 声明a、datas为全局变量
a = 200
datas = ["a", "b", "c"]
f2()
print(a, datas) # 输出:200 ['a', 'b', 'c']
2.3 nonlocal 关键字:嵌套函数修改外层函数变量
适用场景:多层嵌套函数,内层函数修改外层函数局部变量(非全局),不能操作全局变量。
a = 10
datas = [1,2,3]
def f1(n):
a = 200 # f1局部变量
datas = ["a", "b", "c"]
def f2(m):
nonlocal a, datas # 绑定外层f1的局部变量
a = 2000
datas = ["a", "b", "c", "d"]
print(a, "---", datas)
f2(666)
print(a, "===", datas)
f1(10)
print(a, datas, "======")
运行结果:
plaintext
2000 --- ['a', 'b', 'c', 'd']
2000 === ['a', 'b', 'c', 'd']
10 [1, 2, 3] ======
可见:nonlocal 只修改上层函数变量,不会改动最外层全局变量。
三、lambda 匿名函数
3.1 什么是 lambda
lambda 是单行简易无名称函数,无需 def 定义,仅支持一行表达式,自动返回表达式结果,常配合高阶函数使用。
语法:lambda 参数列表: 返回表达式
3.2 基础用法示例
# 1. 无参匿名函数
f2 = lambda: print(888)
f2()
# 2. 无参带返回值
f3 = lambda: (100, 200, 300)
print(f3())
# 3. 单个参数
f4 = lambda x: x + 100
print(f4(50))
# 4. 多参数
f5 = lambda x, y: x + y + 100
print(f5(100, 200))
# 5. 直接调用
print((lambda x, y, z: x + y + z)(10, 20, 30))
3.3 lambda 优缺点
优点:代码简洁,无需单独定义函数,临时回调首选;
缺点:仅单行表达式,不能循环、分支复杂逻辑,无函数名调试困难。
四、高阶函数全解
4.1 高阶函数定义
满足其一即为高阶函数:
参数接收另一个函数;
返回值为函数对象。
Python 内置四大高频高阶函数:sorted、map、filter、reduce(reduce 需导入 functools)
4.2 sorted:自定义排序
核心参数key=函数,用函数返回值作为排序依据,支持 reverse 反转。
# 字典列表排序
datas = [
{"id": 105, "name": "马云", "age": 30},
{"id": 101, "name": "刘强东", "age": 50},
{"id": 102, "name": "张一鸣", "age": 40},
]
# 按age升序
res = sorted(datas, key=lambda e: e["age"])
# 按id降序
res2 = sorted(datas, key=lambda e: e["id"], reverse=True)
print(res)
4.3 map:批量映射转换
作用:遍历可迭代对象,每个元素执行传入函数,返回迭代器。
datas = [
{"id": 105, "name": "马云", "age": 30},
{"id": 101, "name": "刘强东", "age": 50},
]
# 提取所有人名
map_data = map(lambda e: e["name"], datas)
print(list(map_data)) # ['马云', '刘强东']
4.4 filter:条件过滤
作用:保留函数返回 True 的元素,过滤 False 元素。
datas = [
{"id": 105, "name": "马云", "age": 30},
{"id": 101, "name": "刘强东", "age": 50},
]
# 筛选年龄≥40的人
new_datas = filter(lambda e: e["age"] >= 40, datas)
print(list(new_datas))
4.5 reduce:累积归约计算
需要导入from functools import reduce,接收双参数函数,依次累积计算所有元素,最终返回单个结果。
```python
from functools import reduce
datas = [10, 20, 30, 40, 50]
# 求和
r = reduce(lambda a, b: a + b, datas)
print(r) # 150
五、递归函数
5.1 递归三要素
函数内部调用自身;
必须设置递归出口(终止条件,否则无限递归报错);
每次递归向出口靠近。
5.2 经典递归案例
案例 1:1~n 累加
def get_sum(n):
if n == 1: # 递归出口
return 1
else:
return n + get_sum(n-1)
print(get_sum(5)) # 15
案例 2:n 的阶乘
python
运行
def get_mul(n):
if n == 1:
return 1
else:
return n * get_mul(n - 1)
print(get_mul(5)) # 120
案例 3:斐波那契数列
def get_n(n):
if n == 1 or n == 2:
return 1
else:
return get_n(n-1) + get_n(n-2)
print(get_n(10))
5.3 递归注意事项
Python 默认递归深度限制,超深度抛出RecursionError,可通过sys.setrecursionlimit()修改;
递归重复计算效率低,大量循环场景优先 for/while 循环。
六、综合面试总结
global 和 nonlocal 区分
global:修改全局变量,任意函数可用;
nonlocal:仅嵌套函数修改父函数局部变量,不能操作全局;
可变对象不用关键字修改:列表 append 等方法修改内部数据,无需 global;直接赋值才需要;
lambda 搭配高阶函数:sorted/map/filter 最常用,适合简单回调;
四大高阶函数分工
sorted:排序;map:批量转换;filter:筛选;reduce:累计计算;
递归核心:必须写终止条件,避免栈溢出。
总结
本文讲解 Python 函数进阶知识:变量作用域中读取外部变量无需关键字,直接赋值会生成局部变量,修改列表等可变对象内部内容不用声明,global用于修改全局变量,nonlocal用于嵌套函数修改外层函数局部变量;lambda 是单行简易匿名函数,适合临时简单逻辑,常搭配四大高阶函数使用,其中sorted实现自定义排序、map批量转换元素、filter过滤数据、reduce完成序列累计运算;递归函数需要满足自调用、终止出口、逐步靠近出口三大条件,可实现求和、阶乘、斐波那契数列,但存在递归深度限制、运行效率低的问题,大批量计算优先选用循环。
更多推荐

所有评论(0)