一、前言

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完成序列累计运算;递归函数需要满足自调用、终止出口、逐步靠近出口三大条件,可实现求和、阶乘、斐波那契数列,但存在递归深度限制、运行效率低的问题,大批量计算优先选用循环。

更多推荐