函数-递归调用
基本介绍
1.简单来说:递归就是函数自己调用自己,每次调用时传入不同的值
2.递归有助于编程者解决复杂问题,同时可以让代码变得简洁
递归可以解决什么问题
1.各种数学问题:8皇后问题,汉罗塔,阶乘问题,迷宫等
2.各种算法会使用到递归,比如快排,归并排序,二分查找等
3.将用栈解决的问题,递归比较简洁
递归的重要原则
1.执行一个函数时,就创建一个新的空间(栈空间)
2.函数的变量是独立的,比如n变量
3.递归必须向退出递归的条件逼近,否则就是无限递归就出现
4.当一个函数执行完毕,或者遇到return,就会返回,遵守谁调用就返回谁
汉罗塔例子:
def hanoi_tower(num, a, b, c):
"""
输出指定num个盘子移动的顺序
:param num: 指定盘子数
:param a: 表示A柱子
:param b: 表示B柱子
:param c: 表示C柱子
:return:
"""
if num == 1:
print("第一个盘从:", a, "->", c)
else:
# 有多个盘,我们认为只有两个,上面所有的盘和下面所有的盘
# 移动上面所有的盘到B柱子,这个过程会借助到C柱子
hanoi_tower(num - 1, a, c, b)
# 移动最下面的盘
print(f"第{num}个盘从:{a},->,{c}")
# 把上面的所有盘从B柱子移动到C柱子,这个过程会使用到A柱子
hanoi_tower(num - 1, b, a, c)
hanoi_tower(3, "a", "b", "c")
运行结果:
函数作为参数传递
def f1(num1,num2):
max_val=num1 if num1>num2 else num2
return max_val
def f2(num1,num2):
max_val=num1 if num1>num2 else num2
return num1+num2,max_val
上述代码分析:
1.f1和f2都有对两个数求最大值的需求
2.如果有更多的函数也有对两个数,求最大的需求,在每个函数都写一份相同的代码会冗余,而且不利于维护
3.解决方案,编写一个程序(该函数可以返回两个数的最大值)
4.该函数作为参数传给f1,f2就很好
def f3(my_fun, num1, num2, my_fun2):
return my_fun2(num1, num2), my_fun(num1, num2)
# 定义一个函数,可以返回两个数的最大值
def get_max_val(num1, num2):
max_val = num1 if num1 > num2 else num2
return max_val
# 定义函数,可以返回两个数的和
def get_sum(num1, num2):
return num1 + num2
print(f3(get_max_val, 130, 190, get_sum))
运行结果:
注意事项和细节
1.函数作为参数传递,传递的不是数据,而是业务处理逻辑
2.一个函数,可以接收多个函数参数传入
lambda匿名函数
基本介绍
如果我们有这样一个要求,需求将一个函数进行传递,但是这个函数只能使用一次,这时我们可以考虑lambda函数
函数定义
- def关键字,可以定义带有名称的函数,可以重复使用。
- lambda关键字,可以定义匿名函数(无名称)匿名函数只能使用一次
- 匿名函数用于临时创建一个函数,只能使用一次的场景
匿名函数的基本语法
- lambda形参列表:函数体(一行代码)
- lambda关键字表示定义匿名函数
- 形参列表:比如num1,num2.表示接收两个参数
函数体:完成的功能,只能写一行代码,不能写多行代码
def f1(fun, num1, num2):
"""
功能:调用fun返回num1和num2的最大值
:param fun:接受该函数
:param num1:
:param num2:
:return:
"""
print(f"fun的类型:{type(fun)}")
return fun(num1, num2)
# 关键词看如何传入匿名函数调用
"""
1.lambda a,b:a if a>b else b 就是匿名函数
2.不需要return,运算结果就是返回值
"""
max_val=f1(lambda a,b:a if a>b else b,12,10)
print("max_val=",max_val)
运行结果:
局部变量和全局变量
基本介绍
全局变量:在整个程序范围内都可以访问,定义在函数外,拥有全局作用域的变量。
局部变量:只能在函数被声明的函数内访问,定义在函数内部,拥有局部作用域的变量。
#n1是全局变量
n1=100
def f1():
#n2就是局部变量
n2=200
print(n2)
#可以访问全局变量n1
print(n1)
#调用
f1()
print(n1)
#不能访问局部变量n2
运行结果:
无
注意事项
1.未在函数内部重新定义n1,那么默认使用全局变量n1
2.在函数内部重新定义了n1,那么根据就近原则,使用的就是函数内部重新定义的n1
3.在函数内部使用global关键字,(使全局变量变为局部变量,在使用函数后才能改变)可以表明指定使用全局变量。
n1=100
def f1():
print(n1)
f1()
运行结果:
n1=100
def f1():
#n1重新定义
n1=200
print(n1)
f1()
print(n1)
运行结果:
n1 = 100
def f1():
# global关键字表明使用全局变量n1
global n1
n1 = 200
print(n1)
print(n1)
f1()
print(n1)
运行代码: