1. lambda匿名函数
# lambda表⽰的是匿名函数. 不需要⽤def来声明, ⼀句话就可以声明出⼀个函数 # 语法: 函数名 = lambda 参数: 返回值 # 普通的正常的函数 def func(n): return n * n ret = func(9) print(ret) # 匿名函数 a = lambda n: n * n ret = a(9) print(ret) print(a(5)) # 函数的名字可以认为是a # 匿名函数并不是说⼀定没有名字. 这⾥前⾯的变量就是⼀个函数名. 说他是匿名原因# 是我们通过__name__查看的时候是没有名字的. 统⼀都叫lambda. 在调⽤的时候没有什么特别之处.像正常的函数调⽤即可 print(func.__name__) # 查看函数的名字, (函数的名字可能被赋值过,你看到的不一定是它的名字) print(a.__name__) # __name__的值都是<lambda> # 返回值是元祖 def func(x, y): return x, y # 返回的是元组 print(func(1, 2)) # (1,, 2) c = 1, 2 # 1,2 是元组 print(c) # (1, 2) # lambda返回多个值的坑 suiyi = lambda x, y: x, 123 # 这是lambda x, y: x是一个整体,它和后面的123整体是一个元组 print(suiyi) # (<function <lambda> at 0x0000013CA75E9510>, 123) # 多个返回值需要括起来成为一个元素(lamda返回值是一个元素),最后返回一个元组(一个元素) suiyi = lambda x, y: (x, y) print(suiyi(1, 2)) # (1, 2) # 注意: # 1. 函数的参数可以有多个. 多个参数之间⽤逗号隔开 # 2. 匿名函数不管多复杂. 只能写⼀⾏, 且逻辑结束后直接返回数据(太复杂就不要用lamda函数写了) # 3. 返回值和正常的函数⼀样, 可以是任意数据类型 # 笔试题 suiyi = lambda x, y: 1, 2 # 换成数值不显示报错,但是运行不出来 print(suiyi) # (<function <lambda> at 0x00000270F54DC1E0>, 2) print(suiyi(250, 38)) # TypeError: 'tuple' object is not callable # 练习: 匿名函数, 给函数传递2个参数, 返回最大值 # 用三元运算符(只用于2个数的比较) a = lambda x, y: x if x > y else y print(a(6, 9)) # 用max(), (用于多个数的比较) b = lambda x, y: max(x, y) print(b(1, 2)) # 难度升级, 传递多个参数, 返回最大值 fn = lambda *args: max(args) # 单行函数 print(fn(6, 1, 3, 4, 2, 8, 99))
2. sorted()
# sorted 排序函数 # 语法: sorted(Iterable, key=None, reverse=False) # (1) Iterable: 可迭代对象 # (2) key: 排序方案, sorted函数内部会把可迭代对象中的每一个元素交给后面的key # 后面的key计算出一个数字. 作为当前这个元素的权重, 整个函数根据权重进行排序 # (3) reverse: 是否是倒叙. False: 正序, True: 倒叙. (不写就默认是 True: 正序) # 长度 2 3 4 3 3 2 2 lst = ["聊斋", "西游记", "三国演义", "葫芦娃", "水浒传", "年轮", "亮剑"] def func(s): return len(s) # 按照元素的长度大小来排序 # return len(s) % 2 # 按照元素长度除以2的余数大小来排序 ll = sorted(lst, key=func) # func("聊斋", "西游记", ...) print(ll) # 结果: ['聊斋', '年轮', '亮剑', '西游记', '葫芦娃', '水浒传', '三国演义']
3. filter()
# filter 筛选函数 # 语法: filter(function, Iterable) # function: ⽤来筛选的函数. 在filter中会⾃动的把iterable中的元素传递给function. # 然后根据function返回的True或者False来判断是否保留此项数据 lst = [ {"name": "汪峰", "score": 48}, {"name": "章子怡", "score": 39}, {"name": "闫康琪", "score": 97}, {"name": "理想", "score": 90} ] f = filter(lambda el: el['score'] > 60, lst) # 留下的人 print(list(f)) # 结果: [{'name': '闫康琪', 'score': 97}, {'name': '理想', 'score': 90}]
4. map()
# map 映射函数 # 语法: map(function, iterable) 可以对可迭代对象中的每⼀个元素进⾏映射. 分别取执⾏function m = map(lamda el: el**2, lst) # 把后面的可迭代对象中的每一个元素传递给function, 结果就function的返回值 print(list(m)) # 拿出所有值到一个列表里 # 分而治之, 一层一层处理(思想很重要) # map(func1, map(func2, map(func3, lst))) # 计算两个(不只两个)列表中相同位置的数据的和 lst1 = [1, 3, 5, 7] lst2 = [2, 4, 6, 8, 10] # 水桶效应, zip() m = map(lambda x, y, z: x + y + z, lst1, lst2, [5, 1, 2, 3, 6]) print(list(m)) # 结果: [8, 8, 13, 18]
5. 递归函数
# 递归函数, 自己调用自己 # 递归深度. 你可以自己调用自己的次数, # 官方文档中递归的最大深度是1000. 在这之前就会给你报错. count = 1 def func(): global count print("alex是很帅的", count) count = count + 1 func() func()
# 题1 # 遍历D:/TIM文件夹, 打印出所有的文件和普通文件的文件名 # 输出格式 # d:/TIM # 05.pdf # 06.pdf # s15: # day01: # 01xxx # 02xxx import os def func(filepath, n): # 1. 打开这个文件夹 files = os.listdir(filepath) # 2. 拿到每一个文件名 for file in files: # 文件名 # 3. 获取到路径.(文件名没办法直接判断,需要加上路径) f_d = os.path.join(filepath, file) # d:/TIM/文件名 # 4. 判断是否是文件夹 if os.path.isdir(f_d): # 5. 如果是文件夹. 继续再来一遍 print(" "*n, file,":") # 打印文件名 func(f_d, n+1) else: # 不是文件夹. 普通文件 print(" "*n, file) func("d:/TIM", 0)
6. 二分查找
# 使用二分法可以提高效率, 前提条件: 有序序列 # 二分法核心思想: 掐头掐尾取中间, 一次砍一半. # 2**n < 数据量 # n 比较次数 # 100000000 有一亿个数,判断一个数在不在里面, 比较27次就可以 # print(2**27) # 二分法27次可以比较134217728个数 # 二分查找--非递归 lst = [22, 33, 44, 55, 66, 77, 88, 99, 101, 238, 345, 456, 567, 678, 789] n = 66 left = 0 # 左边界 right = len(lst) - 1 # 右边界 while left <= right: # 边界, 当右边比左边还小的时候退出循环 mid = (left + right)//2 # 必须是整除. 因为索引没有小数 if lst[mid] > n: right = mid - 1 # 不出现在右边界,把右边界变成现在的中间并且向左移一位 if lst[mid] < n: left = mid + 1 # 不出现在左边界,把右边界变成现在的中间并且向右移一位 if lst[mid] == n: print("找到了这个数") break else: print("没有这个数") # 递归版本⼆分法 lst = [22, 33, 44, 55, 66, 77, 88, 99, 101, 238, 345, 456, 567, 678, 789] def func(n, left, right): if left <= right: mid = (left + right)//2 if n > lst[mid]: # 在右边 left = mid + 1 # 把左边界变成mid,然后右移一位 # 个人理解: 一层一层函数递归进去,但是结果也要一层一层返回回来到第一层 return func(n, left, right) # 递归 递归的入口 if n < lst[mid]: # 在左边 right = mid - 1 # 把右边界mid,然后左移一位 # 深坑. 函数的返回值返回给调用者 return func(n, left, right) # 递归 if n == lst[mid]: print("找到了") return mid # 通过return返回, 终止递归 # return # 通过return返回. 终止递归 else: print("没有这个数") # 递归的出口 return -1 # 1, 索引+ 2, 什么都不返回, None(避免返回None) # 找66, 左边界:0, 右边界是:len(lst) - 1 print(func(63, 0, len(lst)-1))