递归函数、三元表达式、二分法、列表和字典生成器、匿名函数
一、递归函数
1、关于递归函数
递归函数是直接或间接的调用自己
由此会使函数不间断的调用自己,所以递归一定要有结束条件
默认的递归深度(循环次数)是1000次
递归深度的查看和修改方式
import sys # 引入sys模块 print(sys.getrecursionlimit()) # 查看最大递归深度 # 结果为1000 sys.setrecursionlimit(2000) # 修改最大递归深度 print(sys.getrecursionlimit()) # 结果为2000
2、简单案例
count = 1 def index(): global count count += 1 print('from index', count) index() index()
3、实际应用
# 有5个人,如果A比B大2岁,B比C大2岁,以此类推,现知E18岁,求A的年纪 # 思路:a=b+2 b=c+2 c=d+2 d=e+2 e=18 # 当age=18的时候,循环4次age=age+2 # 或者定义一个函数,让函数返回值依然为该函数名,完成函数递归,代替循环 def age(n): # 定义一个函数 if n == 1: return 18 # 设置结束条件 return age(n - 1) + 2 # 返回值的名字依次减1,值依次加2 print(age(5)) # 打印出n=5时的结果
4、应用进阶
# 要求把列表内的数值全部拆分出来 l = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, ]]]]]]]]]] # 分析:列表是整型+列表额嵌套模式 # 思路:如果是整型,直接打印输出;如果不是整型(也就是列表格式),循环 # 具体方式:定义一个递归函数,如果是整型,直接打印输出 # 如果是列表,递归循环如果 def get_num(l): for i in l: if type(i) is int: print(i) else: get_num(i) get_num(l)
二、三元表达式
1、三元表达式
res = a if 条件 else b
res表示:如果满足条件返回a,否则返回b
2、三元表达式嵌套
res = a if 条件1 else (‘hello’ if 条件2 else ‘world’)
res表示:如果满足条件1,返回a,否则执行(‘hello’ if 条件2 else ‘world’);
‘hello’ if 条件2 else ‘world’,如果满足条件2,返回‘hello’,否则返回‘world’
三次嵌套、四次嵌套,都依次类推
3、实际应用
# 让用户输入判断 cmd = input('username:').strip() res = '帅哥' if cmd == 'ly' else 'dsb' print(res)
三、算法之二分法
算法是解决问题放入高效方法
常见的算法包括:二分法、冒泡算法、选择排序
二分法是指,在顺序排列的组合中,高效找到所需值的一种方法。
具体是不断对比中间的数值,判断所属范围在中间的左边或者右边。
优点是对末尾数值方便快速查找,缺点是查找第一个数值比不了传统方法(for循环遍历查找)
l = [1, 2, 3, 4, 5, 6, 11, 22, 34, 44, 55, 66, 67, 333, 444] def my_half(target_num, l): # # 1. 从列表中取一个中间值 middle_index = len(l) // 2 # 7 # 2. 比较 if target_num > l[middle_index]: # 要找的元素在右边 l_right = l[middle_index + 1:] my_half(target_num, l_right) elif target_num < l[middle_index]: # 要找的元素一定在左边 l_left = l[:middle_index] my_half(target_num, l_left) else: print('找到了,哈哈哈哈') my_half(34, l)
四、列表生成式
1、传统方式:
列表生成器是列表使用的又一种方法,可以实现简单的列表再生成
其他方式也可以实现,且更能满足多种条件下应用
所以一般不使用列表生成式,了解即可
# 现在有一个列表,要求给列表中的每个元素添加‘_dl’ l = ['ly', 'jason', 'tom'] new_list = [] # 定义一个空列表,用于改变后的新内容 for i in l: new_list.append(i + '_dl') # 给l的每一个元素添加‘_dl’ print(new_list)
2、列表生成式
for循环条件下的列表生成式
res = [i + '_dsb' for i in l]
# 现在有一个列表,要求给列表中的每个元素添加‘_dl’ l = ['ly', 'jason', 'tom'] new_list = [] # 定义一个空列表,用于改变后的新内容 res = [i + '_dsb' for i in l] print(res)
if...else条件下的列表生成式
res = [i + '_dsb' if i != 'jason' else i for i in l]
# 现在有一个列表,要求给列表中的每个元素添加‘_dl’,除了jason l = ['ly', 'jason', 'tom'] new_list = [] # 定义一个空列表,用于改变后的新内容 res = [i + '_dsb' if i != 'jason' else i for i in l] print(res)
五、字典生成式
1、传统方式:
# l1中的元素作为字典的k,l2中的元素作为字典的v l1 = ['name', 'age', 'hobby'] l2 = ['ly', 18, 'music'] # 定义一个空字典 new_dict = {} for i in range(len(l1)): # 以l1的长度作为循环的范围,也就是0,1,2,3 new_dict[l1[i]] = l2[i] print(new_dict)
2、字典生成式
补充知识点:enumerate枚举
# l1中的元素作为字典的k,l2中的元素作为字典的v l1 = ['name', 'age', 'hobby'] l2 = ['ly', 18, 'music'] # 补充:enumerate枚举 # 定义一个空字典 new_dict = {} res = {l1[i]: l2[i] for i, j in enumerate(l1)} print(res) # 结果为{'name': 'ly', 'age': 18, 'hobby': 'music'}
六、匿名函数
1.定义
指没有名字的函数
2、格式
lambda 参数:返回值
3、实例对比
1、非匿名函数得出一个数的平方
# 传统方式 # 这是一个得出平方的有参函数 def index(x): return x ** 2 print(index(3)) # 得出结果9
2、匿名函数得出一个数的平方
注意:匿名函数一般不单独使用,匿名函数跟内置函数结合使用才是常规做法
# 匿名函数 lambda x: x ** 2 # x是参数:x**2是返回值 print(lambda x: x ** 2) # 返回at 0x00000240273FBD08> print((lambda x: x ** 2)(3)) # 写入实参,可以得到返回值 # 返回9,注意lambda x: x ** 2 和 实参3 都必须用括号括起来
4、结合内置函数map使用
七、常见的内置函数
1、map 映射
1、语法结构
map(func, *iterables)
func是函数名,*iterables是可迭代对象
2、底层原理
foe循环
3、实例
# 要求:给列表l中的每一个元素平方,得到一个新列表 l = [1, 2, 3, 4, 5] # map映射 map(lambda x: x ** 2, l) # map语法结构map(函数名,可迭代对象) # lambda语法结构 lambda(参数,返回值) # lambda与map的结合使用 res = list(map(lambda x: x ** 2, l)) # map()得出的是内存地址,list(map())才是结果 print(res) # 返回结果[1, 4, 9, 16, 25]
2、zip 拉链
实现两个或连个以上列表对应索引位置的一一结合
(1)传统实现方式
l1 = [1, 2, 3, 4, 5, 6] l2 = ['ly', 'jason', 'tom', 'kevin', 'tony', 'Pony'] # 先定义一个新变量列表,用于存储结果 list_1 = [] for i in range(len(l1)): # len(l1)==6,range(6)结果是[0,1,2,3,4,5],顾头不顾尾 list_1.append((l1[i], l2[i])) # 注意.append()内只能有一个参数,所以必须把两个括起来 print(list_1) # 返回结果[(1, 'ly'), (2, 'jason'), (3, 'tom'), (4, 'kevin'), (5, 'tony'), (6, 'Pony')]
(2)zip实现方式
l1 = [1, 2, 3, 4, 5, 6] l2 = ['ly', 'jason', 'tom', 'kevin', 'tony', 'Pony'] zip(l1, l2) res = list(zip(l1, l2)) print(res) # 返回结果[(1, 'ly'), (2, 'jason'), (3, 'tom'), (4, 'kevin'), (5, 'tony'), (6, 'Pony')]
(3)zip实现两个以上列表的对应
注意:如果列表长度不同,以最短的一个输出
l1 = [1, 2, 3, 4, 5, 6] l2 = ['ly', 'jason', 'tom', 'kevin', 'tony', 'Pony'] l3 = ['a', 'v', 'b', 'c', 'd'] l4 = [111, 222, 333, 444] zip(l1, l2, l3, l4) res = list(zip(l1, l2, l3, l4)) print(res) # 返回结果[(1, 'ly', 'a', 111), (2, 'jason', 'v', 222), (3, 'tom', 'b', 333), (4, 'kevin', 'c', 444)]
3、max和min
(1)传统实现方式
l = [1, 2, 3, 4, 66, 77, 8, 99, ] l.sort() # 升序 # l.sort(reverse=True) # 降序 print(l[-1]) # 通过索引-1求最大值 print(l[len(l) - 1]) # 通过len列表长度-1取最大值 # 结果都是99
(2)max和min实现方式
# 列表
l = [1, 2, 3, 4, 66, 77, 8, 99, ] l4 = [111,222,333] print(max(l)) # 结果是99 print(min(l)) # 结果都是1 print(max(l,l4)) # 结果都是[111, 222, 333] print(min(l,l4)) # 结果都是[1, 2, 3, 4, 66, 77, 8, 99] # 注意:两个列表比较比的是列表的第一个索引值,如果相同继续比较下一位
# 字典 d = { 'ly': 9999999, 'jason': 1000, 'kevin': 2000, 'tom': 20 } ''' 字典暴露的是k值, 按照ASCII码对应的十进制比较 0:48 A:65 a:97 ''' # max(d, key=None) # 底层也是for循环 # 其中d是可迭代对象,key是比较的值,没写默认为None # max函数返回什么值就按照什么值进行比较,所以字典的返回结果还是字段的k print(max(d, key=lambda key: d[key])) # 底层也是for循环 # 返回值为ly print(min(d, key=lambda key: d[key])) # 底层也是for循环 # 返回值为tom
4、filter 过滤
# 要求取出列表l中大于30的元素 l = [1, 2, 3, 4, 66, 77, 8, 99, ] print(list(filter(lambda x: x > 30, l, ))) # 返回值为[66, 77, 99]