函数下

本文深入探讨了递归的概念,通过实例展示了如何使用递归解决阶乘问题,并解释了递归的两个关键条件——基线条件和递归条件。此外,还介绍了高阶函数,包括匿名函数和闭包,并提供了相关示例。最后,通过猴子吃桃问题展示了递归在解决实际问题中的应用。递归虽然高效但可能消耗大量内存,因此在实践中需要谨慎使用。
摘要由CSDN通过智能技术生成

递归函数

  • 递归是解决问题的一种方式,它的整体思想,是将一个大问题分解为一个个的小问题,直到问题无法分解时,在去解决问题
  • 递归式函数有2个条件
    1.基线条件 :问题可以被分解为最小问题,当满足基线条件时,递归就不执行了
    2.递归条件 :可以将问题继续分解的条件

递归函数例题

求取10的阶乘

#方法一:
n = 1
for i in range(1, 11):
    n *= i
print(n)
#用函数封装:
def fun(n):
    r = 1
    for i in range(1, n + 1):
        r *= i
    return r
print(fun(10))
#用递归解决
# 求取10的阶乘
# 10!=  10 * 9!  #递归条件: n! = n * (n-1)! => fun(n) = n*fun(n-1)
# 9! = 9 * 8!
# 1! = 1
def fun(n):  # fun(n) 是为了求取n的阶乘
    if n == 1:
        return 1
    else:# r = n * fun(n - 1)
        return n * fun(n - 1)

print(fun(10))#求10的阶乘

递归的经典解释:
从前有座山,山上有座庙,庙里有个老和尚和小和尚,老和尚给小和尚讲故事:
从前有座山,山上有座庙,庙里有个老和尚和小和尚,老和尚给小和尚讲故事:
从前有座山,山上有座庙,庙里有个老和尚和小和尚,老和尚给小和尚讲故事:。。。。。。
递归简单理解就是自己引用自己 :递归函数就是在函数中自己调用自己

#无穷递归
def fun():
    fun()
fun()
#超过最大递归深度,递归执行次数过多。但其本质还是递归。

递归练习

1.求任意数的任意次幂
例:10**5 (10的5次幂)
用递归方法: 10 ** 5 = 10 * 10 ** 4
10 ** 4 = 10 * 10 ** 3
10 ** 1 = 10

def fun(n, m):
    if m == 1:
        return n
    return n * fun(n, m - 1)


print(fun(10, 5))

2.求一个字符串是否是回文字符串
回文字符串:回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。

def fun(s):
    if len(s) < 2:
        return True
    elif s[0] != s[-1]:
        return False
    return fun(s[1:-1])
print(fun('121'))#True

递归比较吃内存,一般情况下不会用。

高阶函数

  • 接收函数作为参数,或者将函数作为返回值返回的函数就是高阶函数 (满足一个即可)
def fun2(i):
    if i % 2 == 0:
        return True
#判断是否为偶数

def fun(fn):  # fn是函数的参数(形参) 形参等于实参  fn = fun2  
    list1 = []
    for i in range(101):
        if fn(i):  # fn(i) = fun2(i)
            list1.append(i)
    return list1


print(fun(fun2))  

匿名函数

  • 不知道函数名称的一个函数
  1. 防止函数的重名
  2. 不用再去定义函数,使用方便
  3. 可以作为一个传参的工具
  • lambda 函数就是匿名函数
# 语法: lambda 参数:表达式
print((lambda a, b: a + b)(1, 2))#3 
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
s = lambda a: a % 2 == 0
# # filter() 有两个参数,第一个参数(函数)是过滤规则,第二个是过滤的数据
print(list(filter(s, list1)))#filter是一个类,给一个参数列表及规则就可以过滤
#[2,4,6,8,10]

闭包

  • 行成闭包的条件:
    函数嵌套
    将内部函数对象作为返回值返回(这就是一个高阶函数)
    内部函数必须要使用到外部函数的变量
  • 闭包的好处
    通过闭包可以创建一些只有当前函数能访问的变量
    可以将一些私有数据藏到闭包中
  • 保证被内部使用的外部变量不被销毁
def fun_out(num1):

    # 定义一个内部函数
    def fun_inner(num2):
        res = num1 + num2
        print(res)
        # return res 加上这条语句返回值就不是None,就是3了
    return fun_inner
# 函数的调用等于函数的返回值
f = fun_out(1)# fun_out(1)() = fun_inner() = f()
# 内部函数的调用  fun_inner()
print(f(2))结果:3 None 内部函数没有返回值,所以要有结果内部也必须要返回值

易混淆:下面的代码不是一个闭包,因为内部的函数没有用到外部的变量

def fun_out(num1):

    # 定义一个内部函数
    def fun_inner(num2):
        num1 = 10
        res = num1 + num2
        # print(res)
        return res

    print(num1)
    fun_inner(1)
    print(num1)
    return fun_inner
修改外部函数的变量
def fun_out(num1):

    # 定义一个内部函数
    def fun_inner(num2):
        global num1# 把num1b变为一个全局变量,但是num1是可以在最外面修改,是没有意义的,不属于函数内部的变量
        num1 = 10
        res = num1 + num2
        # print(res)
        return res

    #print(num1)
    fun_inner(1)
    #print(num1)
    return fun_inner
def fun_out(num1):

    # 定义一个内部函数
    def fun_inner(num2):
        # global num1
        nonlocal num1  # 告诉解释器,这里使用的不是本地的num1, 是外部变量的num1
        num1 = 10
        res = num1 + num2
        # print(res)
        return res

    print(num1)
    fun_inner(1)
    print(num1)
    return fun_inner

作业

  1. 猴子吃桃问题(递归):
    猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了,求第一天共摘了多少桃子?
def taozi(day):
    if day==1:
        return 1
    return 2*(taozi(day-1)+1)
print(taozi(10))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值