一、递归与二分法

  一)递归

  1、递归调用的定义

  递归调用:在调用一个函数的过程中,直接或间接地调用了函数本身 

  2、递归分为两类:直接与间接

#直接
def func():
    print('from func')
    func()

func()
# 间接
def foo():
    print('from foo')
    bar()

def bar():
    print('from bar')

foo()

  3、递归调用的特点和使用的注意点

递归调用:在调用一个函数的过程中,直接或间接地调用了函数本身
python中的递归效率低,需要在进入下一次递归时保留当前的状态
在其他语言中可以有解决方法:尾递归优化,即在函数的最后一步(而非最后一行)调用自己,尾递归优化:http://egon09.blog.51cto.com/9161406/1842475;但是python又没有尾递归,且对递归层级做了限制

#总结递归的使用:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出
在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出

  4、递归的执行分为两个阶段:递推(询问的过程)和回溯(回答的过程)

 1 #获知age(5)的值
 2 # age(5)=age(4)+2
 3 # age(4)=age(3)+2
 4 # age(3)=age(2)+2
 5 # age(2)=age(1)+2
 6 # age(1)=18
 7 #
 8 # age(n)=age(n-1)+2 #n>1
 9 # age(1)=18 #n=1
10 
11 def age(n):
12     if n == 1:
13         return 18
14     return age(n-1)+2
15 
16 print(age(5))

  5、可以递归的最大深度

 1 #虽然可以设置,但是因为不是尾递归,仍然要保存栈,内存大小一定,不可能无限递归
 2 import sys
 3 sys.getrecursionlimit()  ##获取目前默认递归的最大深度,默认深度是1000
 4 sys.setrecursionlimit(500)  ##更改默认递归的最大深度
 5 n=1
 6 def test():
 7     global n
 8     print(n)
 9     n+=1
10     test()
11 test()

  6、应用场景:有许多层的列表,要取出所有元素——设置结束条件使用递归

l =[1, 2,'list' ,[3, [4, 5, 6, [7, 8, [9, 10, [11, 12, 13, [14, 15,[16,[17,]],19]]]]]]]
def search(l):
    for item in l:
        # if type(item) is list:
        if isinstance(item,list): ##判断数据类型是否是列表
            search(item)
        else:
            print(item)

search(l)

  二)二分法

  1、二分法的产生

一个按照从小到大排列的数字列表中找到指定的数字,遍历的效率太低,用二分法(算法的一种,算法是解决问题的方法)可以极大低缩小问题规模

  2、 二分法的作用:不断将列表切分成两份,减小压力

 1 l = [1,2,5,6,77,1001,1165,2340]
 2 def search(l,num):
 3     print(l)
 4     if len(l) > 1:
 5         mid_index = len(l) // 2 #相除取整
 6         if num > l[mid_index]:
 7             #in the right
 8             l = l[mid_index+1:]
 9         elif num < l[mid_index]:
10             #in the left
11             l = l[:mid_index]
12         else:
13             print('find it')
14             return
15     else:
16         if l[0] == num:
17             print('find it')
18         else:
19             print('not exists')
20         return
21     search(l,num) #重复的可以放在if里面
22 search(l,77)

二、匿名函数

  一)什么是匿名函数

# 有名函数
def f1(m):
print(f1(3))
# 匿名函数
lambda n:n*2

  二)匿名函数的应用场景

匿名函数自带return,只能使用一次
#匿名函数即没有绑定名字的函数,意味着只能使用一次就会回收
应用场景:只使用一次的功能

  三)匿名函数的使用

salaries={
    'egon':3000,
    'alex':10000000,
    'wupeiqi':10000,
    'yuanhao':2000
}

def f1(k):
    return salaries[k]

  1、max、min与 lambda结合

print(max(salaries,key=lambda k:salaries[k]))
print(min(salaries,key=lambda k:salaries[k]))

  2、sorted与lambda结合

print(sorted(salaries,key=lambda k:salaries[k]))
print(sorted(salaries,key=lambda k:salaries[k],reverse=True))

  3、map(映射)与lambda结合

  将原来的元素进行处理后,重新赋值给原变量

l=['alex','egon','wzs','yuanhao']
print(list(map(lambda x:x+'123',l)))

  4、reduce(合并)与lambda结合

  计算0到100数字的和

1 from functools import reduce
2 # reduce(lambda 表达式,计算范围,计算的初始值)
3 res=reduce(lambda x,y:x+y,range(1,100),100)
4 print(res)

  5、filter(过滤)与lambda结合

  过滤出列表中以123结尾的元素

l=['alex123','egon123','wzs123','yuanhao']
print(list(filter(lambda name:name.endswith('123'),l)))

  6、扩展: 拉链函数

l1=[1,2,3]
s1='hello'
res = zip(l1,s1)
print(list(res))

res=zip(salaries.values(),salaries.keys())
print(max(res)[1])
函数递归,匿名、内置行数,模块和包,开发规范
1 t1=(111,'a')
2 t2=(11,'b',123,'c')
3 print(t1 < t2)
元素比较大小:从左到右比较元素的大小

相关文章:

  • 2021-11-11
  • 2022-12-23
  • 2021-09-28
  • 2022-01-12
  • 2022-12-23
  • 2021-08-24
  • 2022-12-23
  • 2021-12-14
猜你喜欢
  • 2021-12-19
  • 2021-07-20
  • 2022-12-23
  • 2022-12-23
  • 2021-10-02
  • 2021-10-15
相关资源
相似解决方案