六.递归与二分法、匿名函数、内置函数
一.递归与二分法
1.1递归调用的定义
递归调用是函数嵌套调用的一种特殊形式,函数在调用时,直接或间接调用了自身,就是递归调用
#直接调用本身 def f1(): print('from f1') f1() f1() #间接调用本身 def f1(): print('from f1') f2() def f2(): print('from f2') f1() f1() # 调用函数会产生局部的名称空间,占用内存,因为上述这种调用会无需调用本身,python解释器的内存管理机制为了防止其无限制占用内存,对函数的递归调用做了最大的层级限制 四 可以修改递归最大深度 import sys sys.getrecursionlimit() sys.setrecursionlimit(2000) def f1(n): print('from f1',n) f1(n+1) f1(1) 虽然可以设置,但是因为不是尾递归,仍然要保存栈,内存大小一定,不可能无限递归,而且无限制地递归调用本身是毫无意义的,递归应该分为两个明确的阶段,回溯与递推
1.2 递归调用应该分为两个明确的阶段:递推,回溯
递归分为两个阶段 1、回溯:回溯就是从外向里一层一层递归调用下去, 回溯阶段必须要有一个明确地结束条件,每进入下一次递归时,问题的规模都应该有所减少(否则,单纯地重复调用自身是毫无意义的) #注意:一定要在满足某种条件结束回溯,否则的无限递归 2、递推:递推就是从里向外一层一层结束递归
# age(5)=age(4)+2 # age)4)=age(3)+2 # age(3)=age(2)+2 # age(2)=age(1)+2 # age(1)=18 # # age(n)=age(n-1)+2 # n > 1 # age(n)=18 #n=1
def age(n): if n == 1: return 18 return age(n-1)+2 #age(4)+2 print(age(5))
总结: 1、递归一定要有一个明确地结束条件 2、没进入下一次递归,问题的规模都应该减少 3、在python中没有尾递归优化
1.3递归取值相关代码
items=[1,[2,[3,[4,[5,[6,[7,[8,[9,[10,]]]]]]]]]]
def tell(l): for item in l: if type(item) is not list: print(item) else: tell(item) tell(items)
nums=[3,5,7,11,13,23,24,76,103,111,201,202,250,303,341] find_num=203 for num in nums: if num == find_num: print('find it') break else: print('not exists')
1.4二分法
nums = [3, 5, 7, 11, 13, 23, 24, 76, 103, 111, 201, 202, 250, 303, 341]
def binary_search(list1, find_num): print(list1) if len(list1) == 0: print('not exist') return mid_index = len(list1) // 2 if find_num > list1[mid_index]: print('in the right') binary_search(list1[mid_index + 1:], find_num) elif find_num < list1[mid_index]: print('in the left') binary_search(list1[:mid_index], find_num) else: print('find it') binary_search(nums, 111)
二.匿名函数
pass
三.内置函数
pass