递归,匿名函数
程序员文章站
2022-03-20 13:14:08
递归 函数的嵌套调用:函数嵌套函数。函数的递归调用:它是一种特殊的嵌套调用,但是它在调用一个函数过程中,有直接间接调用了自身。 直接调用 间接调用 递归必须要有两个明确的阶段: 1. 递推:一层一层递归调用下去,进入下一层递归的问题规模都将会减小 2. 回溯:递归必须要有一个明确的结束条件,在满足该 ......
递归
函数的嵌套调用:函数嵌套函数。函数的递归调用:它是一种特殊的嵌套调用,但是它在调用一个函数过程中,有直接间接调用了自身。
def foo(): print('from foo') foo() foo() # 进入死循环
-
直接调用
import sys # 修改递归层数 sys.setrecursionlimit(10000) def foo(n): print('from foo',n) foo(n+1) foo(0)
间接调用
def bar(): print('from bar') foo() def foo(): print('from foo') bar() bar()
递归必须要有两个明确的阶段:
- 递推:一层一层递归调用下去,进入下一层递归的问题规模都将会减小
- 回溯:递归必须要有一个明确的结束条件,在满足该条件开始一层一层回溯。
递归的精髓在于通过不断地重复逼近一个最终的结果。
def age(n): if == 1: return 26 res = age(n-1)+2 return res print(f"age(5):{age(5)"})
age(5):34
二分法的应用
from random import randint nums = [randint(1, 100) for i in range(100)] nums = sorted(nums) print(nums)
[1, 2, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 10, 11, 11, 11, 11, 12, 13, 13, 15, 16, 16, 20, 21, 21, 23, 24, 26, 26, 27, 28, 28, 31, 33, 33, 34, 35, 38, 38, 39, 40, 42, 43, 45, 45, 46, 46, 47, 47, 51, 52, 52, 53, 53, 55, 55, 56, 56, 57, 57, 57, 58, 59, 61, 62, 64, 66, 66, 67, 68, 69, 69, 71, 72, 72, 74, 74, 75, 76, 78, 78, 79, 79, 79, 79, 80, 82, 85, 88, 89, 90, 90, 91, 91, 91, 94, 99, 99, 100]
def search(search_num,nums): mid_index=len(nums)/2 print(nums) if not nums: print("not exists") return if search_num>nums[mid_index]: nums=nums[mid_index+1:] search(search_num,nums) elif search_num<nums[mid_index]: nums=nums[:mid_index] search(search_num,nums) else: print('find it') search(7,nums)
[1, 2, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 10, 11, 11, 11, 11, 12, 13, 13, 15, 16, 16, 20, 21, 21, 23, 24, 26, 26, 27, 28, 28, 31, 33, 33, 34, 35, 38, 38, 39, 40, 42, 43, 45, 45, 46, 46, 47, 47, 51, 52, 52, 53, 53, 55, 55, 56, 56, 57, 57, 57, 58, 59, 61, 62, 64, 66, 66, 67, 68, 69, 69, 71, 72, 72, 74, 74, 75, 76, 78, 78, 79, 79, 79, 79, 80, 82, 85, 88, 89, 90, 90, 91, 91, 91, 94, 99, 99, 100] [1, 2, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 10, 11, 11, 11, 11, 12, 13, 13, 15, 16, 16, 20, 21, 21, 23, 24, 26, 26, 27, 28, 28, 31, 33, 33, 34, 35, 38, 38, 39, 40, 42, 43, 45, 45, 46, 46, 47, 47] [1, 2, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 10, 11, 11, 11, 11, 12, 13, 13, 15, 16, 16, 20, 21] [1, 2, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7] [6, 6, 7, 7, 7] find it
- 普通版本和递归版本比较
import time def rec_find_num(num, lis): """递归版本""" lis_len = int(len(lis) / 2) # 10.0 binary_num = lis[lis_len] # 10 if len(lis) == 1: print('没找到') return if binary_num > num: lis = lis[:lis_len] rec_find_num(num, lis) elif binary_num < num: # 10 < 18 lis = lis[lis_len + 1:] rec_find_num(num, lis) else: print('找到了') lis = [i for i in range(100000000)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] start = time.time() rec_find_num(4567899900, lis) end = time.time() print(end - start) # 1.1569085121154785 import time lis = [i for i in range(100000000)] def time_count(func): def wrapper(*args, **kwargs): start = time.time() res = func(*args, **kwargs) end = time.time() print(end - start) return res return wrapper @time_count def find_num(num): """普通版本""" for i in lis: if i == num: print('找到了') break else: print('没有被找到') find_num(4567899900) # 2.293410062789917
匿名函数
-
有名函数
我们之前定的函数都是有名函数,它是基于函数名使用。
def func(): print('from func') func() func() func() print(func)
from func from func from func <function func at 0x10518b268>
-
匿名函数
匿名函数,他没有绑定名字,使用一次即被收回,加括号既可以运行。
lambda x, y: x+y
<function __main__.<lambda>(x, y)>
res = (lambda x, y: x+y)(1, 2) print(res)
3
与内置函数联用
1.如果我们想从上述字典中取出薪资最高的人,我们可以使用max()方法,但是max()默认比较的是字典的key。
- 首先将可迭代对象变成迭代器对象
- res=next(迭代器对象),将res当做参数传给key指定的函数,然后将该函数的返回值当做判断依据
salary_dict = { 'nick': 3000, 'jason': 100000, 'tank': 5000, 'sean': 2000 } print(f"max(salary_dict): {max(salary_dict)}") def func(k): return salary_dict[k] print(f"max(salary_dict, key=func()): {max(salary_dict, key=func)}") print( f"max(salary_dict, key=lambda name: salary_dict[name]): {max(salary_dict, key=lambda name: salary_dict[name])}")
max(salary_dict): tank max(salary_dict, key=func()): jason max(salary_dict, key=lambda name: salary_dict[name]): jason
sorted()、filter()、sorted()方法联用。
上一篇: GDAL2.2.4 C#中的编译及使用