递归函数
- 递归是解决问题的一种方式,它的整体思想,是将一个大问题分解为一个个的小问题,直到问题无法分解时,在去解决问题
- 递归式函数有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))
匿名函数
- 不知道函数名称的一个函数
- 防止函数的重名
- 不用再去定义函数,使用方便
- 可以作为一个传参的工具
- 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
作业
- 猴子吃桃问题(递归):
猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了,求第一天共摘了多少桃子?
def taozi(day):
if day==1:
return 1
return 2*(taozi(day-1)+1)
print(taozi(10))