2021-03-23

1.1 递归函数

递归是解决问题的一种方式,它的整体思想,是将一个大问题分解为一个个的小问题,直到问题无法分解时,在去解决问题
递归式函数有2个条件

①. 基线条件 问题可以被分解为最小问题,当满足基线条件时,递归就不执行了
②. 递归条件 可以将问题继续分解的条件

# 求取10的阶乘

# 1!= 1
# 2!= 1*2
# 3!= 1*2*3
# 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))

# 递归函数简单理解就是自己引用自己:递归函数就是在函数中自己调用自己

# 无穷递归
# def fun():
# #     fun()
# #
# # fun()


# 递归的两个条件:
# ① 基线条件:问题可以被分解最小的问题,当满足基线条件的时候,再去解决问题
# ② 递归条件  将问题继续分解的条件
# 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
    return n*fun(n-1) # (递归条件)

print(fun(10))


# def fun(n):  # fun(n) 是为了求取n的阶乘
#     if n == 1:
#        return 1
#     r = n*fun(n-1) # (递归条件)  # 这样会报错

# print(fun(10)) # 10*9*8......2*fun(1)=>2*1 也就是fun(10)结果
相应运行结果:
3628800

# 求任意数的任意次幂
# 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))

# 求一个字符串是否是回文字符串
# 123456789987654321        12345678987654321
# 2345678998765432          234567898765432
# 34567899876543            3456789876543
# 456789987654              45678987654
# 99                        9

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

print(fun('123456789987654321'))
相应运行结果
100000
True

2.1高阶函数

• 接收别的函数对像作为参数,或者将别的函数对像作为返回值返回的函数就是高阶函数

def fun2(i):
    if  i % 2 == 0:
        return True

def fun(fn):
    list1 = []
    for i in range(101):
        if fn(i):
            list1.append(i)
    return list1


print(fun(fun2))
相应运行结果
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100]

3.1 匿名函数

python 使用 lambda 来创建匿名函数。

所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。

lambda 只是一个表达式,函数体比 def 简单很多。
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。 lambda
函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。

# 匿名函数作用
# 1.防止重名
# 2.不用再去定义函数,使用方便
# 3.可以作为一个传参的工具

# lambda 函数就是匿名函数
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 语法: lambda 形式参数:表达式 (实际参数)
print((lambda a, b: a + b)(1, 2))
# filter() 有两个参数,第一个参数是过滤规则,第二个是过滤的数据
s = lambda a: a % 2 == 0
print(list(filter(s, list1)))
相应运行结果
3
[2, 4, 6, 8, 10]

4.1 闭包

  • 将函数对象作为返回值也是高阶函数我们也称为闭包
  • 闭包的好处
  • 通过闭包可以创建一些只有当前函数能访问的变量
  • 可以将一些私有数据藏到闭包中

形成成闭包的条件
函数嵌套
将内部函数对象作为返回值返回
内部函数必须要使用到外部函数的变量或参数

# 保证被内部函数使用的外部变量不被销毁
# 定义一个外部函数
# def fun_out(num1):
#
#     # 定义一个内部函数
#     def fun_inner(num2):
#         res = num1 + num2
#         print(res)
#         # return res
#
#     return fun_inner
#
# # 函数的调用等于函数的返回值
# f = fun_out(1)  # fun_out(1)() = fun_inner() = f()
# # 内部函数的调用 fun_inner()
# # f()
# print(f(2))
# print(f(3))




# 修改外部函数的变量
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

# 函数的调用等于函数的返回值
f = fun_out(1)  # fun_out(1)() = fun_inner() = f()
# 内部函数的调用 fun_inner()
# f()
# print(f(2))
# print(f(3))
相应运行结果
1
10

5.1 Homework(第九讲)

  1. 猴子吃桃问题(递归):
    猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,
    又多吃了一个。以后每天早上都吃了前一天剩的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了,
    求第一天共摘了多少桃子?
    思路分析:
    按倒序来处理:其中n为倒序的天数 f(n)为第n天的个数
    倒序的第一天(第十天)桃子个数为: 1
    基线条件:f(1)=1
    倒序的第二天(第九天)桃子个数为:(1+1)*2 = 4
    倒序的第三天(第八天)桃子个数为:(4+1)*2= 10
    按规推导出 递规条件 :f(n)=(f(n-1)+1)*2
    倒序的第10天(第一天)桃子个数为: ?
def f(n):
    if  n == 1:
        return 1
    else:
        return (f(n-1)+1)*2

print(f(10))
相应结果
1534
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值