一、递归函数
函数递归指的是在调用一个函数的过程中,直接或者间接的调用了该函数本身
# 直接调用
def f1():
print('from f1')
f1()
f1()
# 间接调用
# def func():
# print('from func')
# index()
# def index():
# print('from index')
# func()
# index()
以上两种递归调用都是一个无限循环的过程,但python解释器对函数递归调用的深度做了限制,很好的避免了死循环照成的内存溢出,因此在递归一定次数后,就会抛出异常,要避免出现这种情况,就必须让递归调用在满足某个特定条件下终止。
官网表示:python默认的最大递归深度为1000次,由于电脑硬件原因会出现998、997等情况
# 如何查看、设定递归深度:
import sys
print(sys.getrecursionlimit())
print(sys.setrecursionlimit(2000))
"""
递归分为两个阶段:
1.递推
一层层往下推导答案(每次递归之后复杂度相较于上一次一定要有所下降)
2.回溯
依据最后的结论往后推导出最初需要的答案
注:递归一定要有结束条件!!!
"""
eg1:有5,4,3,2,1五个人,5比4大2岁,4比3大两岁,3比2大两岁,2比1大两岁,1有18岁了。问A多大了
# 伪代码:可能无法运行 但是可以表述逻辑
# 递推
# age(5) = age(4) + 2
# age(4) = age(3) + 2
# age(3) = age(2) + 2
# age(2) = age(1) + 2
# age(1) = 18
# 回溯
# def get_age(n):
# if n == 1:
# return 18
# return get_age(n - 1) + 2
# print(get_age(5)) # 26

eg2:打印出列表中每一个元素(列表除外)
l = [1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,[14,]]]]]]]]]]]]]]
# 1.循环该列表 获取列表内每一个元素
# 2.判断该元素是否是数字 如果是数字 则直接打印
# 3.如果是列表 则循环该列表 获取列表内每一个元素
# 4.判断该元素是否是数字 如果是数字 则直接打印
# 5.如果是列表 则循环该列表 获取列表内每一个元素
# 6.判断该元素是否是数字 如果是数字 则直接打印
# 7.如果是列表 则循环该列表 获取列表内每一个元素
def get_num(l):
for i in l:
if type(i) is int:
print(i)
else:
# 也是for循环 然后判断
get_num(i)
get_num(l)
二、算法之二分法
# 什么是算法?
解决问题的高效方法
# 二分法(二分法能够使用的场景:数据集必须有序)
l = [11, 23, 43, 57, 68, 76, 81, 99, 123, 321, 432, 567, 666, 712, 899, 999, 1111]
# 找321
def my_partner(target_num, l): # target_num=321 l=l
if len(l) == 0:
print('不好意思 我尽力 没找到')
return
# 先获取中间位置索引值
middle_index = len(l) // 2 # 8
# 判断中间索引对应的值比目标值大还是小
if target_num > l[middle_index]:
# 说明要找的元素只可能出现在列表的右侧
l_right = l[middle_index + 1:] # l[9:]
print(l_right)
my_partner(target_num, l_right)
elif target_num < l[middle_index]:
# 说明要找的元素只可能出现在列表的左侧
l_left = l[:middle_index]
print(l_left)
my_partner(target_num, l_left)
else:
print('找到了', target_num)
my_partner(321, l)
"""
[321, 432, 567, 666, 712, 899, 999, 1111]
[321, 432, 567, 666]
[321, 432]
[321]
找到了 321
"""
# my_partner(444, l) # 找不到 需要添加结束条件
# my_partner(11, l) # 要查找的元素在开头 那么还没有依次查找的效率高
# 方式2:直接for循环从左往右依次查找
三、三元表达式
def my_max(a, b):
if a > b:
return a
else:
return b
"""
当功能需求仅仅是二选一的情况下,那么推荐使用三元表达式
"""
def my_max(a, b):
return a if a > b else b
"""
条件成立采用if前面的值 if 条件 else 条件不成立采用else后面的值
三元表达式尽量不要嵌套使用
"""
username = input('username>>>:')
res = 'NB' if username == 'jason' else 'SB'
print(res)
四、列表生成式
name_list = ['jason', 'kevin', 'tony', 'jerry']
# 给列表中所有的人名加上_DSB后缀
'''传统做法'''
# 1.定义一个空列表
# new_list = []
# 2.for循环老列表
# for name in name_list:
# 3.生成新的名字
# new_name = '%s_DSB'%name
# 4.添加到新的列表中
# new_list.append(new_name)
# print(new_list)
'''列表生成式'''
# res = ['%s_DSB' % name for name in name_list]
# print(res)
'''传统做法'''
# 1.定义一个空列表
# new_list = []
# # 2.for循环老列表
# for name in name_list:
# # 3.生成新的名字
# if name == 'jason':
# continue
# else:
# new_name = '%s_DSB'%name
# # 4.添加到新的列表中
# new_list.append(new_name)
# print(new_list)
'''列表生成式'''
# res = ['%s_DSB' % name for name in name_list if name != 'jason']
# print(res)
五、其他生成式
1.字典生成式
name_list = ['jason', 'kevin', 'tony', 'jerry']
# res = {i: j for i, j in enumerate(name_list) if j != 'jason'}
# print(res)
# {1: 'kevin', 2: 'tony', 3: 'jerry'}
2.迭代器
res2 = (i for i,j in enumerate(name_list))
print(res2)
3.枚举
'''
enumerate(l1)
针对该方法使用for循环取值 每次会产生两个结果
第一个是从0开始的数字
第二个是被循环对象里面的元素
还可以通过start参数控制起始位置
'''
# for i, j in enumerate(l1, start=1):
# print(i, j)
六、匿名函数
# 匿名函数:没有名字的函数
"""
语法格式
lambda 形参:返回值
"""
# print(lambda x:x**2)
# def index():
# pass
# print(index)
# print((lambda x: x ** 2)(2))
# res = lambda x: x ** 2
# print(res(2))
'''匿名函数一般不会单独使用 都是配合其他函数一起使用'''
# map() 映射
# l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# def index(n):
# return n ** 2
# print(list(map(lambda x:x**2, l)))
浙公网安备 33010602011771号