打卡Python王者归来--第29天

函数的定义
函数的语法

基本格式如下:

def 函数名(参数1, 参数2, ...):

"""文档字符串(可选)"""

函数体(一组语句) # 缩进

return[返回值1, 返回值2, ...] # 可选

说明及注意事项:

  • def:定义函数的关键字。
  • 函数名:遵循变量命名规则(字母、数字、下划线,不能以数字开头),建议函数名第一个字母小写,要用有意义的函数名称,如 calculate_area() 而不是 func1()。
  • 参数:传递给函数的数据,可以有多个,每个参数值之间逗号隔开也可没有(空括号)。
  • :****冒号表示函数体开始,英文输入格式。
  • 文档字符串(docstring):用引号 """ """ 或三单引号包裹,描述函数功能,推荐编写。
  • return:返回结果。return和返回值都是可有可无,若有多个返回值彼此之间逗号隔开,若无 return,默认返回 None
  • 函数必须先定义后调用
应用举例
python 复制代码
# 无参数无返回值的函数
def say_hello():
    """打印问候语"""
    print("Hello, Python!")
    print("欢迎学习函数!")

# 调用函数
say_hello()


# 有参数有返回值的函数
def add_numbers(a, b):
    """计算两个数的和"""
    result = a + b
    return result

# 调用函数并接收返回值
sum_result = add_numbers(10, 20)
print(f"10 + 20 = {sum_result}")


# 返回多个值的函数
def calculate_rectangle(length, width):
    """计算矩形的面积和周长"""
    area = length * width
    perimeter = 2 * (length + width)
    return area, perimeter

# 调用函数并解包多个返回值
rect_area, rect_perimeter = calculate_rectangle(5, 3)
print(f"矩形面积:{rect_area}, 周长:{rect_perimeter}")


# 数据处理与统计
def analyze_student_scores(scores):
    """
    分析学生成绩数据
    参数:
        scores: 成绩列表
    返回:
        dict: 包含最高分、最低分、平均分等信息的字典
    """
    if not scores:  # 空列表检查
        return {"error": "成绩数据为空"}

    max_score = max(scores)
    min_score = min(scores)
    avg_score = sum(scores) / len(scores)
    pass_count = sum(1 for score in scores if score >= 60)

    return {
        "最高分": max_score,
        "最低分": min_score,
        "平均分": round(avg_score, 2),
        "及格人数": pass_count,
        "总人数": len(scores)
    }

# 测试成绩分析
student_scores = [85, 92, 78, 65, 90, 55, 88, 72, 95, 68]
analysis_result = analyze_student_scores(student_scores)

print("学生成绩分析报告:")
for key, value in analysis_result.items():
    print(f"{key}: {value}")
函数的参数设计
参数类型及顺序汇总

|----------------------------------------|------------------------------------------------------------------|----------------------------|---------------------|
| 参数类型 | 语法格式 | 作用 | 顺序要求 |
| 位置参数(Positional Arguments) | def func(param1, param2, param3): # 函数体 | 按位置传递值,第一个值给第一个参数 | 第 1 位(最优先) |
| 默认参数 (Default Arguments) | def funct(param1, param2="默认值"): # 函数体 | 提供默认值,调用时可省略,默认值是不可变对象 | 第 2 位(位置参数后) |
| 可变位置参数 (Variable Positional Arguments) | def func(*args): | 接收任意数量的位置参数,打包为元组 | 第 3 位(默认参数后,关键字参数前) |
| 关键字仅参数 (Keyword-Only Arguments) | def func(*, a, b): 或 def func(*args, a, b): | 强制使用关键字传递 | 第 4 位(*args 后) |
| 默认关键字仅参数 (Default Keyword-Only) | def func(*, a=5, b=10): | 结合默认值和关键字强制 | 第 4 位(可与关键字仅参数混用) |
| 可变关键字参数 (Variable Keyword Arguments) | def func(**kwargs): | 接收任意数量的关键字参数,打包为字典 | 第 5 位(最后) |
| 关键字参数(Keyword Arguments) | def func(param1, param2): ... func(param2=value2, param1=value1) | 通过关键字传参,顺序无关 | 位置参数之后 |

完整参数顺序示例
deffunc(pos1, pos2, default1=1, default2=2, *args, kw_only1, kw_only2=10, **kwargs):

pass

参数顺序规则:

  • pos1,pos2:位置参数(必填

  • default1, default2: 默认参数(可选)

  • *args(可变位置参数)

  • kw_only1: 关键字专用参数(必需

  • kw_only2: 关键字专用参数(可选,有默认值)

  • **kwargs: 任意数量关键字参数

应用举例
python 复制代码
# 一、位置参数--必须按顺序传递
# 示例 1:传递一个参数
def calculate_square(number):
    """计算一个数的平方"""
    return number ** 2

result = calculate_square(5)
print(f"5 的平方是:{result}")

# 示例 2:传递多个参数
def calculate_area(length, width):
    """计算矩形面积"""
    area = length * width
    return area

area_result = calculate_area(10, 5)
print(f"长 10 宽 5 的矩形面积:{area_result}")

# 二、关键字传参
def create_profile(name, age, city):
    """创建个人信息档案"""
    print(f"姓名:{name}, 年龄:{age}, 城市:{city}")

create_profile(name="张三", age=25, city="北京")
create_profile(city="上海", name="李四", age=30)

# 三、默认值参数--提供默认值,可选择性覆盖
def greet(name, age=18):
    print(f"你好,{name},你今年{age}岁。")

greet("王五")           # 使用默认值  你好,王五,你今年18岁。
greet("赵六", 22)       # 覆盖默认值  你好,赵六,你今年22岁。

# 四、可变位置参数 (*args)--接收任意数量的位置参数
def variable_positional_example(*args):
    """可变位置参数:接收任意数量的位置参数"""
    print(f"args 类型:{type(args)}")  # tuple
    for i, arg in enumerate(args):
        print(f"参数{i}: {arg}")

# 调用
variable_positional_example(1, 2, 3)
variable_positional_example("a", "b", "c", "d")

# 五、关键字仅参数--强制使用关键字传递
def keyword_only_example(*, name, age):
    """关键字仅参数:强制使用关键字传递"""
    print(f"姓名:{name}, 年龄:{age}")

# 调用
keyword_only_example(name="小明", age=20)  # 正确
# keyword_only_example("小明", 20)  # 错误:必须使用关键字

# 六、可变关键字参数 (**kwargs)--接收任意数量的关键字参数
def variable_keyword_example(**kwargs):
    """可变关键字参数:接收任意数量的关键字参数"""
    print(f"kwargs 类型:{type(kwargs)}")  # dict
    for key, value in kwargs.items():
        print(f"{key}: {value}")

# 调用
variable_keyword_example(name="小红", age=22, city="深圳")

# 七、完整示例(所有参数类型)

def complete_example(pos1, pos2,
                     default1=10, default2=20,
                     *args,
                     kw_only_req,
                     kw_only_opt=999,
                     **kwargs):
    """
    完整参数顺序演示

    参数顺序:
    1. pos1, pos2 - 位置参数(必填)
    2. default1, default2 - 默认参数(选填)
    3. *args - 可变位置参数
    4. kw_only_req - 关键字仅参数(必填)
    5. kw_only_opt - 关键字仅参数(选填,带默认值)
    6. **kwargs - 可变关键字参数
    """
    print("=" * 50)
    print(f"位置参数:pos1={pos1}, pos2={pos2}")
    print(f"默认参数:default1={default1}, default2={default2}")
    print(f"可变位置参数:args={args}")
    print(f"必需关键字参数:kw_only_req={kw_only_req}")
    print(f"可选关键字参数:kw_only_opt={kw_only_opt}")
    print(f"可变关键字参数:kwargs={kwargs}")
    print("=" * 50)

# 调用示例
complete_example(
    1, 2,                          # 位置参数
    3, 4,                          # 覆盖默认参数
    5, 6, 7,                       # *args 可变位置参数
    kw_only_req="必须指定",         # 关键字仅参数(必填)
    kw_only_opt=888,              # 关键字仅参数(选填)
    extra1="额外 1",               # **kwargs
    extra2="额外 2"
)
函数的回传值
函数返回值汇总
类型 语法格式 作用 特点 适用场景
回传 None returnreturn None 表示函数无返回值,仅执行副作用(如打印、修改全局变量、写文件) 无值返回 默认行为(无 return 时自动返回 None不适合用于判断交互 日志记录、配置初始化、副作用操作
回传数值数据 (int, float, complex) return 42 return 3.14 返回数字结果,用于计算、比较、状态码等 适合数学运算;可参与表达式 数学计算、评分系统、接口状态码
回传多个数据 (元组 / 解包) return a, b, c自动打包为 tuple 一次返回多个结果,避免多个函数调用 支持解包赋值(x, y = func()保持顺序关联 不能命名字段,可读性较差 分割结果(商/余)、统计分析、坐标点
回传字符串 (str) return "Hello" 返回文本信息,常用于提示、日志、格式化输出 可读性强;拼接、格式化无法直接表示结构化数据 用户提示、API 返回文本、HTML 内容生成
回传字典 (dict) return {"name": "Alice", "age": 25} 返回结构化、命名的数据集合,语义清晰 支持字段命名;易扩展 适合 JSON、配置、对象模型;不能保证顺序(Python 3.7+ 有序) API 响应、用户信息、配置解析、对象封装
回传列表 (list) return [1, 2, 3]return [x for x in ...] 返回有序、可重复的数据组,适合批量处理 支持索引、遍历、切片 可变,适合动态更新 无命名字段,不具语义 数据集合、搜索结果、文件行读取、循环输出
推荐使用顺序(从高到低): 🔹 字典 > 🔹 列表 > 🔹 多个数据(元组) > 🔹 字符串 > 🔹 数值 > 🔹 None
返回值综合应用
python 复制代码
# return 返回值综合应用
import random
from datetime import datetime

# 模拟:假设用户是否联网
has_network = True  # 可切换为 False 模拟断网


def get_weather_data(city="Beijing"):
    """
    模拟从天气 API 获取数据,根据条件返回不同类型的值。
    用于演示 Python 中函数 return 的六种常见类型。
    """

    # 模拟网络延迟或断网(真实项目中可用 requests 和 try/except)
    if not has_network:
        print("📡 无法连接网络,返回 None")
        return None  # 类型1:返回 None(未联网)

    # 模拟真实天气数据
    temp = round(random.uniform(10, 35), 1)  # 温度:10~35℃
    humidity = random.randint(30, 90)  # 湿度:30%~90%
    wind_speed = round(random.uniform(0, 15), 1)  # 风速:0~15 m/s
    condition = random.choice(["Sunny", "Partly Cloudy", "Overcast", "Rainy", "Snowy"])
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    # 类型2:返回数值(当前温度)
    if city == "temperature_only":
        print(f"🌡️ 返回数值:当前温度 {temp}℃")
        return temp

    # 类型3:返回元组(气温, 湿度, 风速)
    if city == "tuple":
        print(f"🌡️  · 气温: {temp}℃, 湿度: {humidity}%, 风速: {wind_speed} m/s")
        return temp, humidity, wind_speed

    # 类型4:返回字符串(天气描述)
    if city == "description":
        desc = f"今天 {condition.lower()},气温 {temp}℃,湿度 {humidity}%,风速 {wind_speed} m/s"
        print("📝 返回字符串:", desc)
        return desc

    # 类型5:返回字典(结构化数据)
    if city == "dict":
        data = {
            "temp": temp,
            "humidity": humidity,
            "condition": condition,
            "timestamp": timestamp
        }
        print("📦 返回字典:", data)
        return data

    # 类型6:返回列表(多个城市预报)
    if city == "multiple_cities":
        cities = ["Beijing", "Shanghai", "Guangzhou", "Shenzhen", "Hangzhou"]
        weather_list = []
        for c in cities:
            t = round(random.uniform(15, 38), 1)
            h = random.randint(40, 95)
            w = round(random.uniform(0, 20), 1)
            cond = random.choice(["Sunny", "Cloudy", "Rain"])
            weather_list.append({
                "city": c,
                "temp": t,
                "humidity": h,
                "wind_speed": w,
                "condition": cond,
                "timestamp": timestamp
            })
        print(f"🏙️ 返回列表 ------ {len(weather_list)} 个城市预报")
        return weather_list

    # 默认:返回北京的字典数据(实际项目中用于正常调用)
    print(f"🌤️ 正常返回:北京天气(字典)")
    return {
        "city": city,
        "temp": temp,
        "humidity": humidity,
        "condition": condition,
        "timestamp": timestamp
    }


if __name__ == "__main__":
    print("=" * 50)
    print("🌦️  测试 get_weather_data() 函数:六种 return 类型")
    print("=" * 50)

    # 1. ✅ return None(未联网)
    print("\n[1] 测试:断网时返回 None")
    has_network = False
    result_none = get_weather_data("Beijing")
    print(f"返回值:{result_none}")

    # 2. ✅ return 数值(温度)
    print("\n[2] 测试:仅返回数值(温度)")
    has_network = True
    temp = get_weather_data("temperature_only")
    print(f"当前温度:{temp}℃")

    # 3. ✅ return 元组(气温, 湿度, 风速)
    print("\n[3] 测试:返回元组")
    weather_tuple = get_weather_data("tuple")
    t, h, w = weather_tuple
    print(f"气温: {t}℃, 湿度: {h}%, 风速: {w} m/s")

    # 4. ✅ return 字符串(描述)
    print("\n[4] 测试:返回字符串")
    desc = get_weather_data("description")
    print(desc)

    # 5. ✅ return 字典(结构化数据)
    print("\n[5] 测试:返回字典")
    data_dict = get_weather_data()
    print(f"城市:{data_dict['city']}, 温度:{data_dict['temp']}℃, 情况:{data_dict['condition']}")

    # 6. ✅ return 列表(多个城市)
    print("\n[6] 测试:返回列表(多个城市预报)")
    cities_data = get_weather_data("multiple_cities")
    for item in cities_data[:3]:  # 只打印前3个
        print(f"  {item['city']}:{item['temp']}℃ ({item['condition']})")
调用函数时参数
调用函数时参数汇总
类型 是否可变 函数内能修改? 是否影响原始数据? 传递建议
list ✅ 是 ✅ 用 append ✅ 会变 lst.copy()/list(lst) 安全
dict ✅ 是 ✅ 修改键值 ✅ 会变 copy.deepcopy() 安全
set ✅ 是 ✅ 使用 add, remove ✅ 会变 s.copy() 安全
tuple ❌ 否 ❌ 不能改 ❌ 不会变 无需副本,只读安全
int / float ❌ 否 ❌ 不能改 ❌ 不会变 完全安全(值传递)
str ❌ 否 ❌ 不能改 ❌ 不会变 完全安全
综合应用
python 复制代码
import copy
from datetime import datetime


# ============================
# 1. 定义学生管理函数(综合调用)
# ============================

def manage_student(
        student_id: int,  # 数值参数
        name: str,  # 字符串参数
        grades: list,  # 列表参数(可变)
        courses: tuple,  # 元组参数(不可变)
        scores: dict,  # 字典参数(可变)
        tags: set,  # 集合参数(可变)
        active: bool = True  # 布尔参数(可选)
):
    """
    管理学生信息,演示各类参数的传递行为。

    :param student_id: 学号(int)
    :param name: 姓名(str)
    :param grades: 成绩列表(list,函数内会被修改)
    :param courses: 课程元组(tuple,只读)
    :param scores: 各科分数(dict,会更新)
    :param tags: 标签集合(set,可修改)
    :param active: 是否活跃(bool,默认 True)
    :return: 更新后的状态字典
    """

    print(f"📋 正在处理学生:{name} (ID: {student_id})")
    print(f"   课程:{courses}")
    print(f"   初始成绩:{grades}")
    print(f"   初始标签:{sorted(tags)}")
    print(f"   是否活跃:{active}")

    # ✅ 修改可变参数:列表、字典、集合
    # 1. 给成绩列表追加"优秀"评价(函数内修改原列表)
    grades.append("优秀")

    # 2. 更新各科成绩(字典修改)
    scores["数学"] = scores.get("数学", 95) + 1  # 累加1分
    scores["英语"] = 88

    # 3. 添加新标签(集合修改)
    tags.add("进步中")
    tags.add("擅长编程")

    # 4. 演示数值变化
    if active:
        print(f"   👍 学生{student_id}当前活跃,状态更新成功。")
    else:
        print(f"   🛑 学生{student_id}为非活跃状态。")

    # 返回合并信息
    return {
        "id": student_id,
        "name": name,
        "avg_grade": round(sum(grade for grade in grades[:-1] if isinstance(grade, (int, float))) / len(grades[:-1]),
                           2) if grades[:-1] else 0,
        "final_scores": scores,
        "tags": tags,
        "updated_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    }


# ============================
# 2. 使用示例(调用函数 + 传入各类型参数)
# ============================

# 原始数据(外部变量)
student_id = 2025001
student_name = "张三"
student_grades = [85, 90, 78]  # 列表
student_courses = ("数学", "英语", "物理")  # 元组
student_scores = {"语文": 80, "数学": 88}  # 字典
student_tags = {"勤奋", "学习认真"}  # 集合
is_active = True

# ❗️重要提醒:如果你想保留原始数据!必须传副本!

# ✅ 方式一:传原始数据(会修改原值 ------ 正常业务逻辑)
print("=" * 60)
print("🟢 方式一:直接传入原始数据(**会修改**)")
print("=" * 60)
result1 = manage_student(
    student_id,
    student_name,
    student_grades,
    student_courses,
    student_scores,
    student_tags,
    is_active
)

print("\n✅ 处理完成,返回结果:")
print(result1)

print("\n🔥 处理后原始数据已变化!")
print(f"🔹 成绩列表(原):{student_grades}")  # → [85, 90, 78, '优秀']
print(f"🔹 分数字典(原):{student_scores}")  # → {'语文': 80, '数学': 89, '英语': 88}
print(f"🔹 标签集合(原):{student_tags}")  # → {'进步中', '学习认真', '擅长编程'}

# ✅ 方式二:传副本(不修改原始数据 ------ 安全模式)
print("\n" + "=" * 60)
print("🟡 方式二:传副本(**不修改**原始数据)")
print("=" * 60)

# 使用 copy 保证数据安全
safe_grades = student_grades.copy()
safe_scores = copy.deepcopy(student_scores)  # 字典嵌套,需深拷贝
safe_tags = student_tags.copy()

result2 = manage_student(
    student_id,
    student_name,
    safe_grades,
    student_courses,  # 元组无需复制
    safe_scores,
    safe_tags,
    is_active
)

print("\n✅ 处理完成,返回结果:")
print(result2)

print("\n📦 处理后原始数据未变!")
print(f"🔹 成绩列表(原):{student_grades}")  # → [85, 90, 78](不变)
print(f"🔹 分数字典(原):{student_scores}")  # → {'语文': 80, '数学': 88}(不变)
print(f"🔹 标签集合(原):{student_tags}")  # → {'勤奋', '学习认真'}(不变)

# ✅ 方式三:数值 & 字符串传参(值传递,完全安全)
print("\n" + "=" * 60)
print("🔵 方式三:数值和字符串参数(完全安全,无法被修改)")
print("=" * 60)


def test_value_params(num, text):
    num = 999  # ❌ 仅修改局部变量,不影响外部
    text = "changed"  # ❌ 不影响原值
    print(f"内部 num: {num}, text: {text}")


original_num = 100
original_text = "Hello"

test_value_params(original_num, original_text)

print(f"外部 num: {original_num}, text: {original_text}")
进一步认识函数
函数文档字符串

函数名称下的"""函数说明文档...."""称为文档字符串 Docstring(document string)缩写,用于解释说明该函数的用途、参数含义、返回值、示例;可以用print(函数名.doc)进行查看函数文档

python 复制代码
# 语法格式
def 函数名(参数):
    """
    函数说明文档(docstring)
    - 用途
    - 参数说明
    - 返回值说明
    - 示例:
        >>> func(3)
        5
    """
    # 函数体
    return 返回值

# 实例说明

def count_even(numbers):
    """
    计算列表中偶数的个数。
    参数:
        numbers (list): 整数列表
    返回:
        int: 偶数的个数
    示例:
        >>> count_even([1, 2, 3, 4, 5, 6])
        3
    """
    return len([x for x in numbers if x % 2 == 0])

# 查看文档
print(count_even.__doc__)
函数是一个对象

在 Python 中,函数是第一类对象(First-class object),可以像变量一样赋值、传递、存储

python 复制代码
# 将函数赋值给变量
def greet(name):
    return f"Hello, {name}!"

# 函数赋值
greet_func = greet
print(greet_func("Alice"))  # Hello, Alice!
函数是数据结构成员

函数可以作为列表、字典、集合等数据结构的元素

python 复制代码
# 定义几个运算函数
def add(a, b):
    return a + b

def multiply(a, b):
    return a * b

def subtract(a, b):
    return a - b

# 将函数放入字典
operations = {
    '+': add,
    '*': multiply,
    '-': subtract
}

# 动态调用
result = operations['+'](5, 3)
print(result)  # 8
函数作为参数传递给其他函数

将函数作为参数传入另一个函数(高阶函数)。

python 复制代码
def apply_operation(func, a, b):
    """接收一个函数和两个参数,执行函数"""
    return func(a, b)

# 使用
print(apply_operation(add, 10, 5))      # 15
print(apply_operation(multiply, 4, 6))  # 24
函数当参数与 *args 不定量参数
  • *args:接收任意数量位置参数,打包为元组
  • 结合函数参数传递,传递函数和可变参数
python 复制代码
# 计算多个数的平均值(用函数处理)
def calculate_average(func, *args):
    """使用函数对可变参数进行处理并返回结果"""
    return func(args)  # 如 sum(args)/len(args)

def sum_list(nums):
    return sum(nums)

# 调用
result = calculate_average(sum_list, 1, 2, 3, 4, 5)
print(result)  # 15(在函数内部处理)


# 用函数筛选并操作不定参数
def process_numbers(func, *args):
    filtered = [x for x in args if x > 0]
    return func(filtered)

def max_value(nums):
    return max(nums)

print(process_numbers(max_value, -1, 2, -3, 5, 1))  # 5
嵌套函数(Nested Function)

函数中定义另一个函数,内部函数可访问外部函数的变量

python 复制代码
# 身份证号校验的嵌套函数
def validate_id_card(id_card):
    """验证身份证号(简略版)"""
    def is_valid_length():
        return len(id_card) == 18

    def ends_with_check():
        last_char = id_card[-1]
        return last_char.isdigit() or last_char.lower() == 'x'

    if is_valid_length() and ends_with_check():
        return "有效"
    else:
        return "无效"

print(validate_id_card("11010119900307123X"))  # 有效
函数作为返回值

函数可以返回另一个函数。

python 复制代码
# 返回不同计算函数
def make_multiplier(factor):
    """根据 factor 返回乘法函数"""
    def multiply(x):
        return x * factor
    return multiply  # 返回函数对象

# 创建特定乘法函数
double = make_multiplier(2)
triple = make_multiplier(3)

print(double(5))   # 10
print(triple(4))   # 12
闭包(Closure)

内部函数是一个 动态产的程序,当它可以记住函数以外的程序所建立的环境变量值时,我们称这个内部函数是闭包。

python 复制代码
def outer():
    b = 10  # inner所使用的变量值

    def inner(x):
        return 5 * x + b  # 引用第2行的变量b

    return inner


b = 2
f = outer()
print(f(b))  # 20
print(f)  # <function outer.<locals>.inner at 0x0000020EA0E0EA60>
print(f.__closure__)  # (<cell at 0x0000020EA0E0EA60: int object at 0x0000020EA0E0EA60>,)
print(f.__closure__[0].cell_contents)  # 10

上述第2行b是一个环境变量,这也是定义在inner()以外的变量,由于第7行inner当作回传值,inner()内的b其实就是第2行所定义的b;其实变量b和inner就构成了一个closure

第12行的f(b),其实这个b将是inner(x)的x参数,所以最后得到5 * 2 + 10,结果是20

其实**closure内是一个元组**,环境变量b就是存在cell_contents内。

python 复制代码
# 计数器(带状态的函数)
def make_counter():
    count = 0  # 外部变量(被闭包捕获)

    def increment():
        nonlocal count  # 声明要修改外部变量
        count += 1
        return count

    return increment  # 返回函数对象

# 创建两个独立计数器
counter1 = make_counter()
counter2 = make_counter()

print(counter1())  # 1
print(counter1())  # 2
print(counter2())  # 1(独立状态)
print(counter1())  # 3
递归函数的设计

递归函数是指在函数执行过程中直接或间接调用自身的函数。递归通常用于解决可以分解为相似子问题的问题。

语法格式
python 复制代码
def recursive_function(参数):
    # 1. 基线条件(终止条件)
    if 条件:
        return 值
    
    # 2. 递归条件
    else:
        return recursive_function(缩小的参数)
适用场景
  • 数学计算(阶乘、斐波那契数列)

  • 树形结构遍历(文件系统、DOM 树)

  • 分治算法(快速排序、归并排序)

  • 回溯算法(迷宫问题、八皇后)

应用举例
python 复制代码
# 案例1:斐波那契数列(经典递归)
def fibonacci(n):
    """
    计算斐波那契数列第 n 项
    参数:n - 正整数
    返回:第 n 个斐波那契数
    """
    if n <= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)


print(fibonacci(6))  # 输出: 8

# 注意:此版本效率极低(指数级时间复杂度),建议用记忆化递归优化:
from functools import lru_cache


@lru_cache(maxsize=None)
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)


print(fibonacci(6))


# 案例2:二 叉树前序遍历(深度优先搜索)
# 递归自然表达树结构的遍历逻辑。
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


def preorder(root):
    if root is None:
        return []
    return [root.val] + preorder(root.left) + preorder(root.right)


# 示例:构建树 [1,2,3] → 1 -> 2 -> 3
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
print(preorder(root))  # 输出: [1, 2, 3]

# 案例3:目录遍历(递归搜索文件夹)
import os


def list_files(directory, indent=0):
    """
    递归列出目录下所有文件和子目录
    参数:directory - 目录路径,indent - 缩进级别
    """
    files = os.listdir(directory)

    for file in sorted(files):
        file_path = os.path.join(directory, file)

        # 打印当前文件/目录,带缩进显示层级
        print(" " * indent + "├── " + file)

        # 如果是目录,递归调用
        if os.path.isdir(file_path):
            list_files(file_path, indent + 4)


list_files(r"D:\pythonProject\python_王者归来", 0)  # 替换为你要遍历的目录路径


# 案例4:汉诺塔问题(经典递归问题)
def hanoi(n, source, auxiliary, target):
    """
    汉诺塔问题求解
    参数:
        n - 盘子数量
        source - 源柱子
        auxiliary - 辅助柱子
        target - 目标柱子
    """
    if n == 1:
        print(f"将盘子 1 从 {source} 移动到 {target}")
    else:
        # 将 n-1 个盘子从 source 移到 auxiliary
        hanoi(n - 1, source, target, auxiliary)
        # 将第 n 个盘子从 source 移到 target
        print(f"将盘子 {n} 从 {source} 移动到 {target}")
        # 将 n-1 个盘子从 auxiliary 移到 target
        hanoi(n - 1, auxiliary, source, target)


hanoi(3, 'A', 'B', 'C')
print(f"\n总共需要 {2 ** 3 - 1} 步")


# 案例5:快速排序
def quick_sort(arr):
    """
    使用递归实现快速排序
    参数:arr - 待排序列表
    返回:排序后的列表
    """
    # 基线条件:空列表或只有一个元素
    if len(arr) <= 1:
        return arr
    else:
        # 选择基准值
        pivot = arr[len(arr) // 2]

        # 小于基准值的元素
        left = [x for x in arr if x < pivot]
        # 等于基准值的元素
        middle = [x for x in arr if x == pivot]
        # 大于基准值的元素
        right = [x for x in arr if x > pivot]

        # 递归排序左右两部分
        return quick_sort(left) + middle + quick_sort(right)


data = [33, 10, 59, 27, 41, 45, 89, 78, 56, 23]
print(f"原始数据:{data}")
sorted_data = quick_sort(data)
print(f"排序结果:{sorted_data}")
相关推荐
幸福清风2 小时前
【Python】运维效率翻倍|批处理日志分割升级Python GUI,一键打包exe无乱码,零基础也能用
python·打包·日志分割
小狗丹尼4003 小时前
JSON 基础认知、数据转换与 Flask 前后端交互全解
python·flask·json
zm-v-159304339865 小时前
Python 数据挖掘从入门到精通:回归 / 分类 / 聚类 / 关联分析完整教程
python·数据挖掘·回归
qq_4176950510 小时前
机器学习与人工智能
jvm·数据库·python
漫随流水10 小时前
旅游推荐系统(view.py)
前端·数据库·python·旅游
yy我不解释11 小时前
关于comfyui的mmaudio音频生成插件时时间不一致问题(一)
python·ai作画·音视频·comfyui
紫丁香12 小时前
AutoGen详解一
后端·python·flask
FreakStudio12 小时前
不用费劲编译ulab了!纯Mpy矩阵micronumpy库,单片机直接跑
python·嵌入式·边缘计算·电子diy
清水白石00814 小时前
Free-Threaded Python 实战指南:机遇、风险与 PoC 验证方案
java·python·算法