深入理解Python闭包与递归:原理、应用与实践


目录

闭包

什么是闭包:

闭包的基本结构:

实现闭包的条件:

1.嵌套函数

2.内函数引用外部函数的变量

3.外部函数返回内部函数

4.外部函数已经执行完毕

递归函数

什么是递归函数:

递归函数条件

[1.必须有个明确的结束条件 ---------递归出口](#1.必须有个明确的结束条件 ———递归出口)

2.每进行更深一步的递归,问题规模相比上一次递归都要有所减少

3.相邻两次重复之间有紧密联系

分析一下这段代码

1.函数定义:

[2. 基准条件(Base Case)](#2. 基准条件(Base Case))

[3. 递归条件(Recursive Case)](#3. 递归条件(Recursive Case))

典型的递归函数的例子

1到100的相加

2.斐波那契数列

递归的优缺点

优点

缺点

递归的应用场景

递归的注意事项


闭包

什么是闭包:

闭包是指在一个函数内部定义的函数,并且这个内部函数引用了外部函数的变量。即使外部函数已经执行完毕,内部函数仍然可以访问和操作这些变量

闭包的基本结构:

python 复制代码
def outer_function(x):
    def inner_function(y):
        return x + y
    return inner_function

closure = outer_function(10)
print(closure(5))  # 输出 15

接下来我为大家解释一下这段代码:

  • outer_function 是外部函数,它接受一个参数 x

  • inner_function 是内部函数,它接受一个参数 y,并且引用了外部函数的变量 x

  • outer_function 返回 inner_function,而不是调用它。

  • 当我们调用 outer_function(10) 时,它返回 inner_function,并且 x 被设置为 10

  • 然后我们调用 closure(5),实际上是在调用 inner_function(5),此时 x 仍然是 10,所以结果是 15

实现闭包的条件:

1.嵌套函数

闭包必须在一个外部函数中定义一个内部函数。也就是说,函数内部再定义一个函数。

python 复制代码
def outer_function():
    def inner_function():
        pass
    return inner_function

2.内函数引用外部函数的变量

内部函数必须引用外部函数的变量(即自由变量)。这是闭包的核心,内部函数通过引用外部函数的变量来"记住"外部函数的环境。

python 复制代码
def outer_function(x):
    def inner_function(y):
        return x + y  # 内部函数引用了外部函数的变量 x
    return inner_function

3.外部函数返回内部函数

外部函数必须返回内部函数(而不是调用它)。这样,内部函数可以在外部函数执行完毕后继续存在,并且仍然可以访问外部函数的变量。

python 复制代码
def outer_function(x):
    def inner_function(y):
        return x + y
    return inner_function  # 返回内部函数,而不是调用它

closure = outer_function(10)
print(closure(5))  # 输出 15

4.外部函数已经执行完毕

闭包的特性在于,即使外部函数已经执行完毕,内部函数仍然可以访问外部函数的变量。这是因为闭包将外部函数的变量"捕获"并保存在内部函数的环境中。

python 复制代码
def outer_function(x):
    def inner_function(y):
        return x + y
    return inner_function

closure = outer_function(10)  # 外部函数执行完毕,x 被设置为 10
print(closure(5))  # 内部函数仍然可以访问 x,输出 15

++总结一下:++

  1. 嵌套函数:在一个函数内部定义另一个函数。

  2. 内部函数引用外部函数的变量:内部函数必须引用外部函数的变量。

  3. 外部函数返回内部函数:外部函数返回内部函数,而不是调用它。

  4. 外部函数已经执行完毕:即使外部函数执行完毕,内部函数仍然可以访问外部函数的变量。

这些条件共同作用,使得闭包能够"记住"其定义时的环境,并在后续调用中继续使用这些环境中的变量。


递归函数

什么是递归函数:

递归函数(Recursive Function)是指在函数的定义中调用函数自身的函数。递归是一种强大的编程技术,特别适用于解决可以分解为相似子问题的问题。理解递归的概念和应用场景,可以帮助你编写更加简洁和优雅的代码。

递归函数条件

1.必须有个明确的结束条件 ---------递归出口

2.每进行更深一步的递归,问题规模相比上一次递归都要有所减少

3.相邻两次重复之间有紧密联系

递归的基本结构

python 复制代码
def recursive_function(parameters):
    if base_case_condition(parameters):  # 基准条件
        return base_case_value
    else:
        # 递归条件
        return recursive_function(modified_parameters)

分析一下这段代码
1.函数定义:
  • recursive_function 是一个递归函数,它接受一个或多个参数 parameters

  • 参数 parameters 是递归函数的输入,通常用于表示当前问题的状态或规模。


    2. 基准条件(Base Case)
  • if base_case_condition(parameters):

    • 这是递归的终止条件。

    • base_case_condition(parameters) 是一个判断条件,用于检查当前参数是否满足递归终止的条件。

    • 如果满足基准条件,函数直接返回 base_case_value,不再进行递归调用。

    • 基准条件的作用:防止无限递归,确保递归最终能够终止。

示例:

在这个例子中,n == 0 是基准条件,当 n0 时,递归停止,函数返回 1


3. 递归条件(Recursive Case)
  • else:

    • 如果基准条件不满足,函数进入递归条件。

    • 在递归条件中,函数会调用自身(即 recursive_function),但传入的参数会被修改(modified_parameters)。

    • 修改参数的目的是将问题规模缩小,逐步逼近基准条件。

      python 复制代码
      def factorial(n):
          if n == 0:  # 基准条件
              return 1
          else:  # 递归条件
              return n * factorial(n - 1)

      在这个例子中,factorial(n - 1) 是递归调用,每次递归调用时,n 的值都会减小,逐步逼近基准条件 n == 0

典型的递归函数的例子

1到100的相加

(一般方法)

python 复制代码
# def add():
#     s=0
#     for i in range(1,101):
#         s +=i
#     print(s)
# add()

采用递归

python 复制代码
# def add(n):
#     if n ==1:
#         return 1
#
#     return n +add(n-1)
# print(add(100))

2.斐波那契数列

python 复制代码
def fibonacci(n):
    if n == 0:  # 基准条件
        return 0
    elif n == 1:  # 基准条件
        return 1
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)  # 递归条件

print(fibonacci(10))  # 输出 55

这个例子中:

  • n01 时,函数返回相应的基准值。

  • 否则,函数返回 fibonacci(n - 1) + fibonacci(n - 2),即前两个斐波那契数的和。

递归的优缺点

优点

  1. 简洁性:递归代码通常比迭代代码更简洁和易读。

  2. 自然表达:对于某些问题(如树遍历、分治算法等),递归提供了一种自然的表达方式

缺点

  1. 性能问题:递归可能会导致大量的函数调用,增加栈的深度,从而影响性能。

  2. 栈溢出:如果递归深度过大,可能会导致栈溢出错误。

  3. 重复计算:在某些情况下(如斐波那契数列的简单递归实现),递归可能会导致大量的重复计算。

递归的应用场景

  1. 树和图的遍历:递归非常适合用于树和图的遍历(如深度优先搜索)。

  2. 分治算法:许多分治算法(如归并排序、快速排序)都使用递归来分解问题。

  3. 动态规划:递归常用于动态规划问题的初始实现,然后可以通过记忆化或迭代来优化。

递归的注意事项

  1. 确保基准条件正确:基准条件是递归终止的关键,必须确保它能够正确终止递归。

  2. 避免无限递归:如果递归条件没有正确地向基准条件靠近,可能会导致无限递归,最终导致栈溢出。

  3. 考虑性能问题:对于性能敏感的应用,可能需要将递归转换为迭代,或使用记忆化来优化递归。

总结一下: 递归函数是一种强大的编程工具,特别适用于解决可以分解为相似子问题的问题。理解递归的基本概念、优缺点和应用场景,可以帮助你编写更加简洁和优雅的代码。然而,递归也需要谨慎使用,特别是在性能敏感的应用中

相关推荐
Calm_dw几秒前
github上传本地文件到远程仓库(空仓库/已有文件的仓库)
python·github
wolf犭良7 分钟前
8、Python 字符串处理与正则表达式实战指南
python·正则表达式
范哥来了15 分钟前
python 数据可视化TVTK库安装与使用
开发语言·python·信息可视化
stevenzqzq16 分钟前
companion object和object 从kotlin转java分析
java·开发语言·kotlin
Imagine Miracle27 分钟前
【Rust】集合的使用——Rust语言基础16
开发语言·后端·rust
ForteScarlet28 分钟前
Kotlin v2.1.20 发布,标准库又有哪些变化?
android·开发语言·kotlin
rzjslSe30 分钟前
【PyTorch基础】PyTorch还支持线性代数运算?PyTorch的内置线性代数运算示例
人工智能·pytorch·python
倔强的石头1061 小时前
【C++指南】string(三):basic_string底层原理与模拟实现详解
开发语言·c++·算法
沉默的八哥1 小时前
CentOS 7.9 安装 Python 3.10 详细步骤及常见问题解决
linux·python·centos
机器鱼3 小时前
1-1 MATLAB深度极限学习机
开发语言·matlab