#函数递归
是一种特殊的函数嵌套调用,在调用一个函数的过程中,又直接或间接的调用该函数本身
递归必须要有两个明确的阶段:
递推:一层一层递归调用下去,强调每进入下一层递归问题的规模都必须有所减少
回溯:递归必须要有一个明确的结束条件,在满足该条件时结束递推
开始一层一层回溯
递归的本质在于通过不断地重复逼近一个最终的结果
python解释器的内存管理机制为了防止其无限制占用内存,对函数的递归调用做了最大的层级限制
(1)递归的调用方式,直接调用、间接调用:
直接调用:
def f1():
print('from f1')
f1()
f1()
间接调用:
def bar():
print('from bar')
foo()
def foo():
print('from foo')
bar()
foo()
import sys
print(sys.getrecursionlimit()) #归队循环的值默认是1000行
sys.setrecursionlimit(10) #可以更改默认循环取值的行数
def foo(n):
print('from foo',n)
foo(n+1)
foo(0)
题目一:递归询问年龄的举例
#理解递归实际是在逼近一个最终的结果(例如询问年龄的举例)
#从第五个人开始每一次的循环都是往记过靠近了一步,
#递归和while循环相比,只需要知道限定好最终结果就行
# age(5) = age(4) + 2 34
# age(4) = age(3) + 2 32
# age(3) = age(2) + 2 30
# age(2) = age(1) + 2 28
# age(1) = 26
# age(n) = age(n-1) + 2 #n > 1
# age(1) = 26 #n = 1
def age(n):
if n == 1:
return 26 #回溯要有一个明确的结束条件
res=age(n-1)+2
return res
print(age(5))
题目二:递归取嵌套列表的值
#递归取嵌套列表的值
num=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]]
def tell(num):
for n in num:
if type(n) is list: #判断for循环取出的是不是列表类型
tell(n)
else:
print(n)
tell(num)
# 输出结果为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(2)二分法在里边中查找到指定的一个数字
nums=[1,3,7,9,12,23,34,45,56,67,78,89,100]
def search(search_num,nums):
print(nums)
if len(nums) == 0:
print('不在列表中')
return
mid_index=len(nums) // 2
if search_num > nums[mid_index]:
#确定在右半边查找
nums=nums[mid_index+1:] #nums范围赋值给右半边
search(search_num,nums)
elif search_num < nums[mid_index]:
#确定在左半边查找
nums=nums[:mid_index] #nums范围赋值给右半边 #[1, 3, 7, 9, 12, 23] [1, 3, 7] [1]
search(search_num,nums)
else:
print('找到了')
search(23,nums)
输出结果为:
[1, 3, 7, 9, 12, 23, 34, 45, 56, 67, 78, 89, 100]
[1, 3, 7, 9, 12, 23]
[1, 3, 7]
[1]
找到了
(3)匿名函数的格式和应用
匿名函数:没有绑定名字,用一次就被回收
普通函数
def func(x,y): func=函数的内存地址
return x+y
func(1,2)
演变为匿名函数格式为:
print(lambda x,y:x+y) #没有赋值,打印结果是函数的内存地址
print((lambda x,y:x+y)(1,2)) #x+y相当与return x+y
(4)max函数取字典中的value值的最大值(min取最小值)
max的工作原理
1、首先将可迭代对象变成迭代器对象
2、res=next(可迭代器对象),将res当作参数传给key指定的函数,然后将该函数的返回值当作判断依据
salaries={
'egon':3000,
'alex':100000000,
'wupeiqi':10000,
'yuanhao':2000
}
方式一:有名函数
def func(k):
return salaries[k] #将字典每次next取出的key值传给func函数,然后通过func函数返回每个对应的value值,做判断依据
print(max(salaries,key=func)) #next(iter_s) salaries可迭代对象
print(min(salaries,key=func)) #取value最小值
#赋值思路分析;
'egon', v1=func('egon')
'alex', v2=func('alex')
'wupeiqi', v3=func('wupeiqi')
'yuanhao', v4=func('yuanhao')
方式二:匿名函数实现格式如下
print(max(salaries,key=lambda k:salaries[k]))
(5)sorted函数 从大到小排序
sorted()函数,例如列表中的参数,实现从小到大排列
sorted:分类、挑选的意思 reverse:颠倒
l=[3,2,5,1,2,7,9]
print(sorted(l,reverse=False)) #默认参数reverse=False从小到大排列
print(sorted(l,reverse=True)) #默认参数reverse=False从大到小排列
(6)map函数 映射
实验效果:使用map映射函数将每个名字后面添加good
map的工作原理
1 首先将可迭代对象变成迭代器对象
2 res=next(可迭代器对象),将res当作参数传给第一个参数指定的函数,
然后将该函数的返回值当作map的结果之一
names=['张三','李四','王五','赵六']
方式一:列表推导式
print([name+'good' for name in names])
方式二:map+无参函数调用
name=map(lambda x:x+"good",names)
print(name) #在python2中直接打印出来就是列表
print(list(name)) #在python3中,name有iter和next,所以更加优化空间输出结果为迭代器
(7)filter函数 过滤
# filter过滤
names=['张三good', '李四good', '王五', '赵六good']
方式一:
print([name for name in names if name.endswith('good')])
方式二:
name=filter(lambda x:x.endswith('good'),names)
print(list(name))