一.匿名函数(lambda)
语法: lambda 参数: 返回值
函数名统一都叫lambda
1.把普通函数转换成匿名函数
def func(n) return n * nret = func(9)print(ret)
a = lambda n: n * nret = a(9)print(ret)
其中a可以认为是函数名,但是在__name__中函数名统一是lambda
print(func.__name__) #查看函数名print(a.__name__) #__name__的值都是
def func(a, b) return a + bx = lambda a, b : a+bprint(x(a , b))
def func(x, y) return x, ys = lambda x, y :(x, y)#如果不放(),s会被分为两部分 lambda x, y :x和yprint(s(250, 38))
fn = lambda *args :max(args) #匿名函数一定是一行函数print(fn(1,3,8,56))#56
二.sorted() 排序函数
语法:sorted(iterable, key, reverse)
key:排序规则.
运行流程: 把可迭代的对象中是每一个元素交给后面的key函数来执行.
得到一个数字(权重).通过这个数字进行排序
lst = ["聊斋", "西游记", "三国演义", "葫芦娃", "水浒传", "年轮", "亮剑"]def func(s) return len(s)li = sorted(lst, key = func)print(li)#key: 排序方案, sorted函数内部会把可迭代对象中的每一个元素拿出来交给#后面的key,后面的key计算出一个数字. 作为当前这个元素的权重, 整个函根#据权重进行排序
lst = [ { 'name':"汪峰","age":48}, { "name":"章子怡",'age':38}, { "name":"alex","age":39}, { "name":"wusir","age":32}, { "name":"赵一宁","age":28} ]ll = sorted(lst, key=lambda el: len(el['name']), reverse=True)print(ll)
三.filter() 过滤函数
语法: filter(function, iterable)
运行流程;把可迭代对象中的数据交给前面的函数进行筛选.函数返回True或者False
#普通函数lst = ["张无忌", "张铁林", "赵一宁", "石可心","马大帅"]def func(el) if el[0] == "张" return False #不想要的 else: return True #想要的f = filter(func, lst)print("__iter__" in dir(f)) # 判断是否可以进行迭代for e in f: print(e)#匿名函数f = filter(lambda el :el[0] != "张", lst)print("__iter__" in dir(f)) # 判断是否可以进行迭代for e in f: print(e)
lst = [ { "name":"汪峰", "score":48}, { "name":"章子怡", "score":39}, { "name":"赵一宁","score":97}, { "name":"石可心","score":90} ] f = filter(lambda el: el['score'] < 60 , lst) # 去16期的人 print(list(f))
四.map() 映射函数
语法: 把可迭代对象中的数据交给前面的函数进行执行,返回值就是map()的处理结果
lst = [1,4,7,2,5,8]li = []#第一种方法:算法for el in lst: li.append(el**2)#第二种方法:普通函数def func(el) return el**2m = map(func, lst)print(list(m))#第三种方法:匿名函数m = map(lambda el: el**2, lst)print(list(m))# 把后面的可迭代对象中的每一个元素传递给function, 结果就是function返#回值
map(func1, map(func2, map(func3 , lst)))
map(func1, map(func2, map(func3 , lst))) 当我们处理的数据过大时可以用分而治之的思想(如人工智能中的数据处理)
五.递归函数(默认递归函数是死循环)
1.定义:函数自己调用自己
2.递归函数的深度: 1000. 到不了1000就会停止(深度可以自己设置)
import syssys.setrecursionlimit()
count = 1def func(): global count print("alex是很帅的", count) count = count + 1 func()func() 递归深度. 你可以自己掉用自己的次数,官方文档中递归最大深度是1000. 在这之前就会给你报错
3.递归函数的用处
3.1处理相似的操作
# 遍历 D:/sylar文件夹, 打印出所有的文件和普通文件的文件名import osdef func(filepath, n): # d:/sylar/ # 1,打开这个文件夹 files = os.listdir(filepath) # 2. 拿到每一个文件名 for file in files: # 文件名 # 3. 获取到路径 f_d = os.path.join(filepath, file) # d:/sylar/文件名/ # 4. 判断是否是文件夹 if os.path.isdir(f_d): # 5. 如果是文件夹. 继续再来一遍 print("\t"*n, file,":") # 打印文件名 func(f_d, n + 1) else: # 不是文件夹. 普通文件 print("\t"*n, file) func("d:/sylar",0)
3.2传播病毒(要在每个文件夹下的每个文件投放病毒)
3.3杀毒
3.4求阶乘
def func(n,s): #计算n的阶乘 if n > 0: s = n * s n = n - 1 return func(n,s) else: return sret = func(8,1)print(ret)
3.5斐波那契(如计算第400个数, 不超过4000000(400万)最多计算几次)
def func(n,i,a,b):#a第一个数,b第二个数,i是第几次计算 c = a + b # 第三个数 if n > i: a = b b = c i+=1 return func(n,i,a,b ) else: return cret = func(400,3,1,1)print(ret)
def func(n,i,a,b):#a第一个数,b第二个数,i是第几次计算 c = a + b # 第三个数 if n > c: a = b b = c i+=1 return func(n,i,a,b ) else: return iret = func(4000000,3,1,1)print(ret)
4.递归函数中的return 返回值,返回给上一层调用者
六.二分法
1.二分法的核心: 掐头去尾取中间,一次砍一半
2.两种算法:常规循环,递归循环
lst = [22, 33, 44, 55, 66, 77, 88, 99, 101 , 238 , 345 , 456 , 567 , 678 , 789 ]n = 79for el in lst: if el == n: # O(1) print("找到了") breakelse: print("没有")
使用二分法可以提高效率, 前提条件:有序序列
lst = [22, 33, 44, 55, 66, 77, 88, 99, 101 , 238 , 345 , 456 , 567 , 678 , 789]n = 88left = 0right = len(lst)-1while 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("找到了这个数") breakelse: 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: # 边界 print("哈哈") mid = (left + right)//2 if n > lst[mid]: left = mid + 1 return func(n, left, right) # 递归 递归的入口 elif n < lst[mid]: right = mid - 1 # 深坑. 函数的返回值返回给调用者 return func(n, left, right) # 递归 elif n == lst[mid]: print("找到了") return mid # return # 通过return返回. 终止递归 else: print("没有这个数") # 递归的出口 return -1 # 1, 索引+ 2, 什么都不返回, None# 找66, 左边界:0, 右边界是:len(lst) - 1ret = func(70, 0, len(lst) - 1)print(ret) # 不是None
def binary_search(ls, target): left = 0 right = len(ls) - 1 if left > right: print("不在这里") middle = (left + right) // 2 if target < ls[middle]: return binary_search(ls[:middle], target) elif target > ls[middle]: return binary_search(ls[middle+1:], target) else: print("在这里")binary_search(lst, 567)
切片二分法很难确定位置
3.给一x位数,2**n 最多要查找n次 时间复杂度 o(1)~o(n)
七.最快速的查询讯方式(时间复杂度最低,空间复杂度最低)
查询某个元素是否在某个序列中
lst1 = [5,6,7,8]
lst2 = [0,0,0,0,0,0,0,0,0] #9个0
for el in lst1:
lst2[el] = 1
o(1) #时间复杂度是1
解释: 查询某列表中lst是否存在某个元素a,
1.先建立一个列表,列表中有lst中最大值加1个零
2.当lst2[a] == 1是该元素存在列表中,当lst2[a]==0时该元素不存在列表中
八总结
filter()和map()一样得到的是地址,需要遍历才能得到结果