Python函数进阶:8 大核心知识点 + 实战案例,从可变参数到 lambda 全掌握 – 小白编程笔记

Python函数进阶是从「会写基础函数」到「写出优雅高效代码」的关键一步。在之前的函数入门篇里,我们掌握了函数的定义、基础参数和返回值;这篇文章会把函数的进阶知识讲透,包括可变参数、递归、作用域、lambda匿名函数等,每一个知识点都配了可直接运行的代码、详细注释和新手避坑指南,帮你彻底吃透Python函数的进阶用法。

Python函数进阶 核心知识体系总览图

图1:Python函数进阶核心知识体系总览

一、可变参数 *args 与 **kwargs:让函数更灵活

当我们写函数时,经常会遇到「参数个数不确定」的场景,比如要计算任意多个数字的和、打印用户的任意自定义信息。这时候就需要用到Python的可变参数:*args 用来接收任意数量的位置参数,**kwargs 用来接收任意数量的关键字参数,这是函数进阶最实用的技巧之一。

1. *args:可变位置参数

*args 会把我们传入的所有位置参数,自动打包成一个 元组(tuple),在函数里直接用 args 就能拿到所有参数。

# 计算任意多个数字的和,不管传几个数都能算
def add(*args):
    total = 0
    # 遍历args(元组),把每个数加起来
    for num in args:
        total += num
    return total

# 测试:传3个数、4个数都可以,不用修改函数
print(add(1, 2, 3))       # 输出:6
print(add(10, 20, 30, 40)) # 输出:100

2. **kwargs:可变关键字参数

**kwargs 会把我们传入的所有关键字参数,自动打包成一个 字典(dict),在函数里用 kwargs 就能拿到所有键值对。

# 打印用户信息,支持任意字段,不用提前定义参数
def print_info(**kwargs):
    # 遍历字典,打印每个字段和对应的值
    for k, v in kwargs.items():
        print(f"{k}:{v}")

# 测试:传name、age、city,甚至更多字段都可以
print_info(name="小明", age=18, city="北京")
# 输出:
# name:小明
# age:18
# city:北京

3. 组合使用:参数顺序必须严格遵守

当多种参数同时出现在函数定义里时,顺序必须严格遵循:位置参数 → 默认参数 → *args → **kwargs,顺序错了会直接触发语法报错,这是新手最容易踩的坑!

# 正确的参数顺序:位置参数a → 默认参数b → *args → **kwargs
def func(a, b=10, *args, **kwargs):
    print(f"位置参数a={a}, 默认参数b={b}")
    print(f"可变位置参数args={args}")
    print(f"可变关键字参数kwargs={kwargs}")

# 测试调用
func(1, 2, 3, 4, x=5, y=6)
# 输出:
# 位置参数a=1, 默认参数b=2
# 可变位置参数args=(3, 4)
# 可变关键字参数kwargs={'x': 5, 'y': 6}

4. *args/**kwargs 解包用法:快速传递参数

在调用函数时,我们可以用 * 解包元组、** 解包字典,把批量参数一次性传给函数,不用手动逐个填写,让代码更简洁。

# 定义一个加法函数
def add(a, b):
    return a + b

# 1. 用*解包元组,快速传递位置参数
nums = (10, 20)
print(add(*nums)) # 等价于 add(10, 20),输出:30

# 2. 用**解包字典,快速传递关键字参数
info = {"name":"小明", "age":18}
print_info(**info) # 等价于 print_info(name="小明", age=18)

Python函数进阶 *args与**kwargs参数类型对比表

图2:*args与**kwargs核心区别对比


二、递归函数:自己调用自己的编程技巧

递归函数,简单说就是「在函数内部调用自己」。用递归可以用非常简洁的代码,解决复杂的问题,比如阶乘、斐波那契数列、汉诺塔等。但递归有两个必须满足的核心条件:基线条件(终止递归)+ 递归条件(缩小问题规模),否则会无限递归导致栈溢出。

经典案例1:阶乘计算

阶乘的定义是 n! = n × (n-1) × (n-2) × … × 1,用递归实现非常简单。

# 递归实现阶乘:n! = n × (n-1)!
def factorial(n):
    # 基线条件:n=1时,直接返回1,终止递归(必须有!)
    if n == 1:
        return 1
    # 递归条件:n × 阶乘(n-1),不断缩小问题规模
    return n * factorial(n-1)

# 测试:计算5的阶乘 5! = 5×4×3×2×1 = 120
print(factorial(5)) # 输出:120

经典案例2:斐波那契数列

斐波那契数列的规律是:第1项=1,第2项=1,从第3项开始,每一项等于前两项之和。

# 递归实现斐波那契数列:第n项 = 第n-1项 + 第n-2项
def fib(n):
    # 基线条件:n≤2时,直接返回1
    if n <= 2:
        return 1
    # 递归条件:第n项 = 前两项之和
    return fib(n-1) + fib(n-2)

# 测试:计算第10项斐波那契数
print(fib(10)) # 输出:55

递归使用注意事项(新手必看)

  • 必须有基线条件:没有终止条件会无限递归,导致程序崩溃(栈溢出)
  • Python默认最大递归深度约1000层:处理大数据量时慎用递归,优先用循环
  • 递归代码简洁但效率低:可以用「记忆化」优化重复计算,提升效率

Python函数进阶 递归函数执行流程图解

图3:递归函数核心执行流程


三、变量作用域:局部vs全局,代码可访问范围

变量的作用域,决定了代码能在哪些位置访问这个变量。搞懂作用域,能帮你避免「变量污染」「变量未定义」等常见bug。核心分为两类:局部作用域(函数内)全局作用域(函数外)

1. 局部变量:函数内定义,仅函数内可访问

在函数内部定义的变量,就是局部变量,只能在这个函数里访问,函数外无法访问。

def func():
    # 局部变量num,仅在func函数内可访问
    num = 10
    print(num) # 函数内可以正常打印

func() # 调用函数,输出:10
# print(num) # 函数外访问会报错:NameError: name 'num' is not defined

2. 全局变量:函数外定义,整个程序可访问

在函数外部定义的变量,就是全局变量,整个程序(包括函数内)都可以访问(但默认只能读取,不能修改)。

# 全局变量num,整个程序都可以访问
num = 100

def func():
    print(num) # 函数内可以读取全局变量,输出:100

func()
print(num) # 函数外也可以访问,输出:100

3. global 关键字:函数内修改全局变量

如果要在函数内修改全局变量,必须用 global 关键字声明,否则Python会把它当成局部变量,不会修改全局变量。

num = 100 # 全局变量

def func():
    global num # 声明:这里的num是全局变量,不是局部变量
    num = 200   # 修改全局变量的值

func()
print(num) # 全局变量被修改,输出:200

4. nonlocal 关键字:嵌套函数修改外层局部变量

如果是嵌套函数(函数里套函数),内层函数要修改外层函数的局部变量,需要用 nonlocal 关键字声明。

def outer():
    num = 10 # 外层函数的局部变量
    def inner():
        nonlocal num # 声明:这里的num是外层函数的局部变量
        num = 20
        print(f"内层函数修改后:{num}")
    inner()
    print(f"外层函数访问:{num}") # 外层函数能看到修改后的值

outer()
# 输出:
# 内层函数修改后:20
# 外层函数访问:20

四、匿名函数 lambda:一次性的简洁函数

lambda 表达式,用来创建一次性、简单的匿名函数,语法极度简洁,不用给函数命名,适合写单行的简单逻辑,常配合高阶函数(如 map、filter、sorted)使用。

1. lambda 基础语法

lambda 的语法非常简单:lambda 参数: 表达式,表达式的结果就是函数的返回值,只能有一个表达式,不能写多行。

# 用lambda创建一个加法函数
add = lambda a, b: a + b
print(add(10, 20)) # 调用函数,输出:30

# 等价于普通函数:
# def add(a, b):
#     return a + b

2. 经典案例:配合 sorted 自定义排序

lambda 最常用的场景,就是给 sorted 函数做排序键,实现自定义排序规则。

# 学生列表,每个元素是字典,包含姓名和年龄
students = [
    {"name": "小明", "age": 18},
    {"name": "小红", "age": 16},
    {"name": "小刚", "age": 20}
]

# 用lambda作为排序键,按年龄升序排序
sorted_students = sorted(students, key=lambda x: x["age"])
print(sorted_students)
# 输出:按年龄从小到大排序的学生列表

3. 配合 map、filter 使用:批量处理数据

map 用来对列表的每个元素执行操作,filter 用来过滤列表元素,配合 lambda 可以用一行代码完成批量处理。

# 1. map:对列表每个元素执行操作(比如给每个数乘2)
nums = [1, 2, 3, 4]
double = list(map(lambda x: x*2, nums))
print(double) # 输出:[2, 4, 6, 8]

# 2. filter:过滤列表元素(比如只保留偶数)
even = list(filter(lambda x: x%2 == 0, nums))
print(even) # 输出:[2, 4]

五、高阶函数:函数式编程的核心

高阶函数的定义很简单:接收函数作为参数,或者返回函数作为结果的函数。它是函数式编程的核心,能让代码更灵活、更抽象,适合封装通用逻辑。

经典案例:函数作为参数,实现通用计算

# 通用计算函数,接收两个数和一个操作函数作为参数
def calculate(a, b, operation):
    # 调用传入的操作函数,返回结果
    return operation(a, b)

# 定义不同的操作函数(也可以用lambda)
add = lambda x, y: x + y
sub = lambda x, y: x - y

# 用同一个calculate函数,实现不同的计算
print(calculate(10, 5, add)) # 加法,输出:15
print(calculate(10, 5, sub)) # 减法,输出:5

六、综合实战案例:把进阶知识用起来

案例1:用递归实现汉诺塔(经典算法)

汉诺塔是递归的经典应用,用递归可以用几行代码解决这个复杂问题。

# 汉诺塔递归实现
# n:盘子数量,a:起始柱,b:中间柱,c:目标柱
def hanoi(n, a, b, c):
    # 基线条件:只有1个盘子,直接从a移到c
    if n == 1:
        print(f"{a} → {c}")
        return
    # 递归条件:把n-1个盘子从a移到b(用c做中间柱)
    hanoi(n-1, a, c, b)
    # 把最下面的1个盘子从a移到c
    print(f"{a} → {c}")
    # 把n-1个盘子从b移到c(用a做中间柱)
    hanoi(n-1, b, a, c)

# 测试:3层汉诺塔
hanoi(3, "A", "B", "C")

案例2:用 lambda + sorted 实现多条件排序

用 lambda 可以实现多条件排序,比如先按年龄升序,再按姓名升序。

# 学生列表,包含姓名和年龄
students = [
    {"name": "Bob", "age": 18},
    {"name": "Alice", "age": 18},
    {"name": "Charlie", "age": 20}
]

# 多条件排序:先按年龄升序,再按姓名升序
sorted_students = sorted(students, key=lambda x: (x["age"], x["name"]))
for s in sorted_students:
    print(s)
# 输出:
# {'name': 'Alice', 'age': 18}
# {'name': 'Bob', 'age': 18}
# {'name': 'Charlie', 'age': 20}

七、高频易错点避坑指南:新手一次性避开

可变参数顺序错误

参数顺序必须严格遵循:位置参数 → 默认参数 → *args → **kwargs,顺序错会直接报语法错

递归无基线条件,导致栈溢出

递归必须有明确的终止条件(基线条件),否则会无限递归,导致程序崩溃

函数内修改全局变量未加 global

不加 global 会创建局部变量,不会修改全局变量,这是新手最容易踩的坑之一

lambda 只能有一个表达式

lambda 是单行匿名函数,不能写多行复杂逻辑,语法有严格限制

延伸学习推荐

想深入学习官方文档,可查看Python官方函数进阶文档
学完本篇内容,建议回顾Python函数入门全攻略,夯实基础,做到融会贯通。

八、核心知识点总结:快速复习

  • *args:接收任意位置参数,自动打包为元组
  • **kwargs:接收任意关键字参数,自动打包为字典
  • 递归函数:函数内调用自身,必须有基线条件终止递归
  • 作用域:局部变量仅函数内可访问,global/nonlocal 用于修改变量
  • lambda 表达式:匿名单行函数,常配合 sorted、map、filter 使用
  • 高阶函数:可接收/返回函数,实现灵活的函数式编程

本文是Python零基础入门系列的进阶篇,承接函数入门内容。更多新手能直接上手的Python教程,可查看往期内容:
Python输入输出与格式化技巧
Python变量与变量名全解析

本文为「小白编程笔记」原创 · Python函数进阶篇
版权声明:本文所有内容(含代码、图片、文字)均为原创,未经授权禁止任何形式的转载、抄袭、洗稿
如需转载,请联系作者获得授权,并在正文开头显著位置标注原文链接和作者信息!
下一篇预告:Python 面向对象编程,从类到对象,彻底掌握 OOP!

文章标签:
Python函数进阶
Python零基础
Python进阶
Python函数
lambda
递归

2人评论了“Python函数进阶:8 大核心知识点 + 实战案例,从可变参数到 lambda 全掌握 – 小白编程笔记”

  1. Pingback: 零基础学 Python 核心编程:7 大核心主题 + 实战进阶全攻略 - 小白 编程 笔记

  2. Pingback: Python核心编程:7大核心主题+实战进阶全攻略,小白一站式学Python - 小白 编程 笔记

发表评论

滚动至顶部
渝公网安备50022402001073号  |  渝ICP备2026004448号   © 2026 小白编程笔记