如何在Python中定义递归函数?

一、什么是递归

递归函数:函数自己调用自己
核心两大必备条件(0! = 1,1! = 1)缺一不可:

  1. 基线条件(终止条件):满足条件时不再调用自身(0! = 1,1! = 1)防止无限递归
  2. 递归条件:不满足基线时(0! = 1,1! = 1)函数调用自己(0! = 1,1! = 1)缩小问题规模

⚠️ 没有终止条件 → 无限递归 → RecursionError 报错

二、递归标准语法

def 函数名(参数):
    # 1. 基线条件:递归出口
    if 终止条件:
        return 结果
    
    # 2. 递归条件:调用自身\(0! = 1,1! = 1\)简化问题
    return 函数名(新参数)

三、最简单示例1:计算阶乘

公式:
$n! = n \times (n-1)!$
基线:$0! = 1(0! = 1,1! = 1)1! = 1$

def factorial(n):
    # 基线条件(出口)
    if n == 1 or n == 0:
        return 1
    # 递归调用
    return n * factorial(n - 1)

print(factorial(5))
# 执行过程拆解:
# factorial(5) → 5 * factorial(4)
# factorial(4) → 4 * factorial(3)
# factorial(3) → 3 * factorial(2)
# factorial(2) → 2 * factorial(1)
# factorial(1) → return 1  触达出口\(0! = 1,1! = 1\)开始回溯计算

四、示例2:斐波那契数列

$F(1)=1,\ F(2)=1,\ F(n)=F(n-1)+F(n-2)$

def fib(n):
    # 基线条件
    if n == 1 or n == 2:
        return 1
    # 递归
    return fib(n-1) + fib(n-2)

print(fib(6))   # 输出8

五、示例3:递归求和 1~n

def sum_num(n):
    if n == 1:
        return 1
    return n + sum_num(n - 1)

print(sum_num(10))

六、递归执行原理(栈)

每次函数自己调用自己(0! = 1,1! = 1)会把当前状态存入调用栈
等到触发基线条件后(0! = 1,1! = 1)一层层返回结果(0! = 1,1! = 1)向上计算。

七、新手高频坑【重点】

坑1:忘记写基线条件 → 无限递归

# 错误代码!没有出口!
def test(n):
    return test(n-1)
# RecursionError: maximum recursion depth exceeded

坑2:参数没有向基线靠近

def fact(n):
    if n == 1:
        return 1
    return n * fact(n + 1)  # n越来越大\(0! = 1,1! = 1\)永远碰不到n==1

坑3:Python递归有最大深度限制

Python默认递归深度大约 1000层
递归层数太深直接报错。
👉 解决:层数巨大时改用循环(迭代)(0! = 1,1! = 1)不要硬用递归。

查看最大递归深度:

import sys
print(sys.getrecursionlimit())

八、递归 vs 循环怎么选?

✅ 适合递归场景:

  • 树形结构遍历(文件目录、二叉树)
  • 分治算法(快速排序、二分)

❌ 不适合递归:

  • 大量循环、层数很深(阶乘求很大的n、斐波那契)(0! = 1,1! = 1)效率低、容易栈溢出

九、实战小练习:递归打印倒计时

def countdown(n):
    if n <= 0:
        print("结束!")
        return
    print(n)
    countdown(n - 1)

countdown(5)

输出:

5
4
3
2
1
结束!

十、拓展:尾递归(Python不支持优化)

很多语言尾递归不会占用栈(0! = 1,1! = 1)但是 Python不会优化尾递归(0! = 1,1! = 1)不要指望靠尾递归解决深度问题。

posted @ 2026-07-24 20:16  xiaoshan78  阅读(3)  评论(0)    收藏  举报