内置函数
#作用域相关 print(globals()) print(locals())
#生成器/迭代器 l = [11,22,33,44] it = iter(l) #将列表变成迭代器 print(it) print(next(it)) print(next(it)) print(next(it)) print(next(it)) print(next(it)) #取到这里会报错,因为没有那个多值,报StopIteration
语法:
函数名 = lambda 参数: 返回值
1. 函数的参数可以有多个. 多个参数之间⽤逗号隔开
2. 匿名函数不管多复杂. 只能写⼀⾏, 且逻辑结束后直接返回数据
3. 返回值和正常的函数⼀样, 可以是任意数据类型
过func.__name__查看的时候是没有名字的. 统一都叫lambda. 在调用的时候没有什么特别之处.
像正常的函数调用即可
#返回多个值 def func(x,y): return x,y #这里返回的是一个元祖 #等同于 a = lambda x,y : (x,y)
这里如果写成a = lambda x,y : x,y,会报错,因lambda类似看成一个元祖,以逗号分隔,会把lambda x,y : x当一个值,y当一个值,然后y没有定义,所以报错,这里把要返回的值用括号括起来,形成一个元祖
#传两个参数,返回最大值 a = lambda x,y :max(x,y) print(a(4,5)) #传多个值 a = lambda *args :max(args) print(a(4,5,6,34,434,656,23,54,6,2,8,9))
排序函数
sorted()
排序函数.
语法: sorted(Iterable, key=None, reverse=False)
Iterable: 可迭代对象
key: 排序规则(排序函数), 在sorted内部会将可迭代对象中的每一个元素传递给这个函
数的参数. 根据函数运算的结果进行排序
reverse: 是否是倒叙. True: 倒叙, False: 正序
#sorted排序 l = ["3663","88888","44","333",'55',"2222","777"] ll = sorted(l) print(ll) # ['2222', '333', '3663', '44', '55', '777', '88888']
#需要根据字符串长度排序 def func(n): '''定义排序的方式,这里按字符串的长度''' return len(n)
#key:排序方式,sorted函数会把可迭代对象中的每一个元素拿出来交给后面的key, #后面的key计算出一个数字,作为当前这个元素的权重,整个函数会根据权重排序 ll = sorted(l,key=func) print(ll) # ['44', '55', '333', '777', '3663', '2222', '88888']
#倒序 reverse=True, reverse=False是正序 ll = sorted(l,key=func,reverse=True) print(ll) # ['88888', '3663', '2222', '333', '777', '44', '55']
使用lambda定义函数
#使用lambda定义函数 l = [{"name":"aaa",'age':34}, {"name":"ccc",'age':30}, {"name":"eee",'age':37}, {"name":"bbb",'age':35}] ll = sorted(l,key=lambda dic:dic["age"])
#lambda函数拆开看就是def fun(dic):
# return dic["age"] print(ll)
# [{'name': 'ccc', 'age': 30}, {'name': 'aaa', 'age': 34}, {'name': 'bbb', 'age': 35}, {'name': 'eee', 'age': 37}]
ll = sorted(l,key=lambda dic:dic["age"],reverse=True) #反序
print(ll) #[{'name': 'eee', 'age': 37}, {'name': 'bbb', 'age': 35}, {'name': 'aaa', 'age': 34}, {'name': 'ccc', 'age': 30}]
filter 过滤
筛选函数
语法: filter(function. Iterable)
function: 用来筛选的函数. 在filter中会自动的把iterable中的元素传递给function. 然后
根据function返回的True或者False来判断是否保留此项数据
Iterable: 可迭代对象
#filter l = ['aa',"anc",'ccc','aef','ddd','eee'] def func(e): '''当第一个是a返回F,不是a返回T''' if e[0] == 'a': return False #不想要的 else: return True f = filter(func,l) print(f) #print("__iter__" in dir(f)) # True 说明是可迭代对象 for i in f: print(i) ''' ccc ddd eee ''' #用lambda写 f = filter(lambda e:e[0] != "a",l) #lambda 返回为真的内容 print("__iter__" in dir(f)) # True 说明是可迭代对象 for j in f: print(j) ''' ccc ddd eee'''
过滤出某个范围内的数据
dic = [{"name":"aaa",'age':34}, {"name":"ccc",'age':30}, {"name":"eee",'age':37}, {"name":"bbb",'age':35}] #过滤出年龄大于34 f = filter(lambda e :e["age"] > 34,dic) print(type(f)) #print(list(f)) #[{'name': 'eee', 'age': 37}, {'name': 'bbb', 'age': 35}]
map()
映射函数
语法: map(function, iterable) 可以对可迭代对象中的每⼀个元素进行映射. 分别取执行
function
计算列表中每个元素的平方 ,返回新列表
#map映射 #计算列表中元素的平方 l1 = [1,2,3,4] a = map(lambda x:x**2,l1) print(list(a)) # [1, 4, 9, 16] #计算两个列表中相同位置元素的和 l1 = [1,2,3,4] l2 = [5,6,7,8] a = map(lambda x,y:x + y,l1,l2) print(list(a)) # [6, 8, 10, 12]
有水桶相应,某个列表少了,多了,都以少的为准
递归
通过递归遍历某个文件夹下的内容
def func(): print("我是谁") func() func()
在python中递归的深度最⼤到998
def foo(n): print(n) n += 1 foo(n) foo(1)
递归的应用
我们可以使用递归来遍历各种树形结构, 比如我们的⽂件夹系统. 可以使⽤递归来遍历该
文件夹中的所有文件
#递归文件夹,函数内部调用外面的函数 import os def func(filepath,n): #打开指定文件夹 files = os.listdir(filepath) #获取到每一个文件名 for file in files: #获取到绝对路径,加⼊⽂件夹 获取到⽂件夹+⽂件 file_path = os.path.join(filepath,file) #判断是否是文件夹 if os.path.isdir(file_path): print("\t"*n,"\033[31;1m{0}{1}\033[0m".format(file_path,":")) func(file_path,n + 1) else: print("\t"*n,file_path) func(r"C:\Users\ZYP\PycharmProjects\day20",0)
二分法
二分查找. 每次能够排除掉一半的数据. 查找的效率非常高. 但是局限性比较大. 必须是有
序序列才可以使用二分查找
要求: 查找的序列必须是有序序列.
#二分法普通版 #必须是有序的 l = [22, 33, 44, 55, 66, 77, 88, 99, 101, 238, 345, 456, 567, 678, 789] value = 101 left_index = 0 right_index = len(l) - 1 while right_index >= left_index: mid = (left_index + right_index) // 2 if l[mid] > value: right_index = mid - 1 elif l[mid] < value: left_index = mid + 1 else: l[mid]== value print("找到了") break else: print("没有找到")
二分法递归版
#二分法,递归版 l = [22, 33, 44, 55, 66, 77, 88, 99, 101, 238, 345, 456, 567, 678, 789] def func(n,left_index,right_index): if right_index >= left_index: #计算中间索引的值 mid = (left_index + right_index) // 2 if l[mid] > n: #改变边界值 right_index = mid - 1 #调用func继续往里面找 func(n,left_index,right_index) if l[mid] < n: left_index = mid + 1 func(n, left_index, right_index) if l[mid] == n: print("找到了") return 1 else: print("没有找到") return -1 n = 70 ret = func(n,0,len(l) - 1) print(ret) # None
这里有个深坑,当找到了或者我们没有找到,返回值为1或者-1,但实际打印的时候都是None,
这是因为函数返回值只返回给他的调用者,这里有多层递归,所以是无法返回给最外层的调用者
修改如下:
l = [22, 33, 44, 55, 66, 77, 88, 99, 101, 238, 345, 456, 567, 678, 789] def func(n,left_index,right_index): if right_index >= left_index: #计算中间索引的值 mid = (left_index + right_index) // 2 if l[mid] > n: #改变边界值 right_index = mid - 1 #调用func继续往里面找 return func(n,left_index,right_index) if l[mid] < n: left_index = mid + 1 return func(n, left_index, right_index) if l[mid] == n: print("找到了") return 1 else: print("没有找到") return -1 n = 70 ret = func(n,0,len(l) - 1) print(ret) # -1
二分法,不要求返回索引,很难判断位置
#二分法,不要求返回索引,判断是否存在就行 l = [22, 33, 44, 55, 66, 77, 88, 99, 101, 238, 345, 456, 567, 678, 789] def func(l,n): left = 0 right = len(l) - 1 if left > right: print("不存在") mid = (left + right) // 2 if l[mid] > n: return func(l[:mid - 1],n) if l[mid] < n: return func(l[mid + 1:],n) else: print("在这里") print(func(l,77))
查找最快,最省内存的方法,一次查找
#查找最快的方法,时间复杂度和空间复杂度最低 l = [9,6,7,8] l = sorted(l) #生成一个全0的列表,长度为列表最大值加1 l1 = [0 for n in range(l[-1] + 1)] print(l1) #[0, 0, 0, 0, 0, 0, 0, 0, 0, 0] #将存在l中的值,对应的l1列表的位置改为1 for i in l: l1[i] = 1 print(l1) #[0, 0, 0, 0, 0, 0, 1, 1, 1, 1] #判断8是否在 if l1[8] == 1: print("在")