本节主要内容
1.lambda函数 匿名函数
2.sorted() 排序函数
3.filter() 筛选函数
4.map() 映射函数
5.递归函数 (自己调用自己)
6.二分法 (掐头去尾取中间)
一、lambda 匿名函数
只适用于一些简单的需求的设计,一句话函数
1、语法:
函数名 = lambda 参数: 返回值
注意:
1.函数的参数可以有多个,多个参数用逗号隔开
2.匿名函数不管多复杂,只能写一行,且逻辑结束后直接返回数据
3.返回值和正常函数一样,可以是任何数据
4.匿名函数不是没有名字,指的是匿名的意思是通过__name__查看时是没有名字的,统一叫lambda
fe:写法和多个参数的示例
a = lambda n: n**n # 匿名函数, 一般不会用来做复杂的操作
r = a(3)
print(r)
print(a.__name__) # <lambda> 匿名函数有名字. 统一叫lambda
# 写一个lambda 给函数传递两个参数, a, b 计算a+b的结果
a = lambda m, n: m + n
# 写一个lambda 计算字符串长度并返回 # len()
a = lambda s: len(s)
二、sorted() 排序函数
语法:
sorted(Iterable, key = None, reverse = False)
Iterable: 可迭代对象
key: 排序规则(函数),sorted内部会将可迭代对象的每一个元素传递个这个函数作为参数,根据函数的运算结果进行排序
reverse: 是否倒叙, True: 倒叙; False: 正序
fe:根据key里面的函数进行排序
lst = ["易", "贾克斯", "赵信", "德玛西亚", "皇子", "刀妹"]
# 按照文字的长短来排序
def func(s):
return len(s)
s = sorted(lst, key=func) # 把列表中的每一个元素传递给func. 根据func返回值进行排序
print(s)
fe2: 根据字典里面的年龄,进行排序
lst=[{'id':3,'name':'taihei','age':18},
{'id':1,'name':'alex','age':28},
{'id':2,'name':'taibai','age':58},
{'id':4,'name':'henhei','age':38}]
# 根据年龄排序
def func(s):
return s['age']
print(sorted(lst, key=lambda dic:dic["age"])) # 根据年龄排序
三、filter() 筛选函数
语法:
filter(function, Iterable)
function: 用来筛选的函数。 在filter中会自动的把Iterable中的元素传递给function,然后根据function
返回的True;则保存,否者,则去掉。
Iterable: 可迭代对象
fe: 根据function返回的True或False,来保存数据
lst = ["渴望", "年轮", "家有儿女", "蜗居", "49天", "浪漫满屋"]
# 把后面的可迭代对象中的每一个元素交给前面的函数。 根据函数返回的True或者False。 判断是否保留该元素
f = filter(lambda s: len(s) > 2, lst)
print("__iter__" in dir(f))
for el in f:
print(el)
lst=[{'id':3,'name':'taihei','age':18},
{'id':1,'name':'alex','age':28},
{'id':2,'name':'taibai','age':58},
{'id':4,'name':'henhei','age':38}]
# 筛选年龄大于等于38的人
print(list(filter(lambda ren: ren['age']>=38, lst)))
四、map() 映射函数
语法:
map(function, Iterable)
对可迭代对象中的每一个元素进行映射,分别执行function操作,返回新的迭代对象,需要变量接收它(新的)
fe: 对旧的可迭代对象,执行function后,全部接收,返回新的
lst = [2, 3, 4 ,5, 6, 7, 1]
# 计算列表中的每一项的平方
# 映射
# 把可迭代对象中的每一个元素拿出来交给前面的函数执行. 保留最后的执行结果
m = map(lambda x: x*x, lst)
for el in m:
print(el)
# 给出一个列表
lst = ["alex_123", "alex_456", "wusir_123", "wusir_456", "alex_789"]
#
# 正确的用户名: alex
# 密码:456
# alex_456
# 第一种方法
print(list(map(lambda s : " yes" if s=="alex_456" else "false" , lst)))
# 第二种方法
print(list(map(lambda s: s.split("_")[0] == 'alex' and s.split("_")[1] == "456",lst)))
五、递归(函数自己调用自己,缺点占内存)
在函数中调用函数本身,就是递归
python中最大的递归深度为1000,但实际操作中不会让你到达1000,
每递归一次就要开辟一片新的一模一样的内存空间,非常占内存,增加了空间复杂度,不能用于复杂的算法
由第三点可以得出,当递归有返回值时,需要写return,传递最终返回值. 否则有可能接收不到返回值(因为函数的返回值是返回给调用者)
fe:遍历文件夹的所有文件,及打印所有文件名(非文件夹的名字)
import os
def func(path, ceng): # path传绝对路径,层用缩进来体现文件夹的所属关系(父子级),
lst = os.listdir(path) # os.listdir(路径) 打开文件夹获取所有的所有内容(所有的文件名含文件夹名字)
for el in lst: # 当前文件夹的所有文件名(包括文件夹名字)
# 拼接真实路径
file_real_path = os.path.join(path, el) # os.path.join(路径, 文件名) 拼接路径和文件名, 使得可以使用这个文件名
if os.path.isdir(file_real_path): # os.path.isdir(拼接好的路径和文件名的变量) 判断是文件夹还是文件
# 递归的入口
print(" " * ceng, el)
func(file_real_path, ceng + 1) # 重复刚才的操作
else: # 不是文件夹,是文件
#递归的出口
print(" " * ceng, el)
func(r"E:a", 0)
5.1 操作系统(os)相关的一些操作
os : 和操作系统相关的一些功能
os.listdir("d:/") 帮我们打开一个文件夹. 返回文件夹内的所有内容(文件的名字)
os.path.join("马化腾","马云") 马化腾/马云
os.path.isdir(路径) 判断这个路径是文件夹还是文件
六、二分法(三种算法)
必须是有序的序列,才能使用二分法
每次能排除一半的数据,效率非常高,局限很大就在要有序的序列
fe: 普通的算法查找一个数
lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963] # 时间复杂度. n
# 让用户输入一个数n. 判断这个n是否出现在lst中
n = int(input("请输入一个数字n:")) # 56
for el in lst:
if n == el:
print('出现了')
break
else:
print("没出现")
fe1: 非递归的二分法,须掌握,面试通常问这个
lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963]
n = int(input("请输入一个数:"))
left = 0 # 左边界
right = len(lst) - 1 # 右边界
while left <= right: # 当左边边界大于右边界的时候,说明不在列表中
mid = (left + right) // 2 # 中间位置的索引
if n > lst[mid]: # n大于中间的数,说明要往mid右边查找
left = mid + 1 # 新的左边界等于mid 向右移一位
elif n < lst[mid]:
right = mid - 1 # 新的右边界等于mid向左移一位
else:
print("存在")
break
else:
print("不存在")
fe2: 递归二分法,方法一:通过改变左右边界查找
lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963]
def binary_search(lst, n, left, right): # 改变的左右边界
if left > right:
return False
mid = (left + right) // 2 # 每次用中间的那个值去判断
if n > lst[mid]:
left = mid + 1
# 当递归有返回值的时候. 需要写return. 否则有可能接收不到返回值
return binary_search(lst, n, left, right) # 此处必须加return, 接收返回值
elif n < lst[mid]:
right = mid - 1
return binary_search(lst, n, left, right) # 此处必须加return, 接收返回值
else:
print("找到了")
return True
n = int(input("请输入一个数字n:")) # 178
ret = binary_search(lst, n, 0, len(lst)-1)
print(ret)
fe3: 二分法,方法二,通过切割列表查找
lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963]
# 切换列表
def binary_search(lst, n):
if len(lst) == 0:
return False
left = 0
right = len(lst) - 1
mid = (left + right) // 2
if n > lst[mid]:
# 当递归有返回值的时候. 需要写return. 否则有可能接收不到返回值
return binary_search(lst[mid+1:], n) # 每判断一次对列表进行切片
elif n < lst[mid]:
return binary_search(lst[:mid], n) # 每判断一次对列表进行切片
else:
print("找到了")
return True
n = int(input("请输入一个数字n:")) # 178
ret = binary_search(lst, n)
print(ret)
本节主要内容
1.lambda函数 匿名函数
2.sorted() 排序函数
3.filter() 筛选函数
4.map() 映射函数
5.递归函数 (自己调用自己)
6.二分法 (掐头去尾取中间)
一、lambda 匿名函数
只适用于一些简单的需求的设计,一句话函数
1、语法:
函数名 = lambda 参数: 返回值
注意:
1.函数的参数可以有多个,多个参数用逗号隔开
2.匿名函数不管多复杂,只能写一行,且逻辑结束后直接返回数据
3.返回值和正常函数一样,可以是任何数据
4.匿名函数不是没有名字,指的是匿名的意思是通过__name__查看时是没有名字的,统一叫lambda
fe:写法和多个参数的示例
a = lambda n: n**n # 匿名函数, 一般不会用来做复杂的操作
r = a(3)
print(r)
print(a.__name__) # <lambda> 匿名函数有名字. 统一叫lambda
# 写一个lambda 给函数传递两个参数, a, b 计算a+b的结果
a = lambda m, n: m + n
# 写一个lambda 计算字符串长度并返回 # len()
a = lambda s: len(s)
二、sorted() 排序函数
语法:
sorted(Iterable, key = None, reverse = False)
Iterable: 可迭代对象
key: 排序规则(函数),sorted内部会将可迭代对象的每一个元素传递个这个函数作为参数,根据函数的运算结果进行排序
reverse: 是否倒叙, True: 倒叙; False: 正序
fe:根据key里面的函数进行排序
lst = ["易", "贾克斯", "赵信", "德玛西亚", "皇子", "刀妹"]
# 按照文字的长短来排序
def func(s):
return len(s)
s = sorted(lst, key=func) # 把列表中的每一个元素传递给func. 根据func返回值进行排序
print(s)
fe2: 根据字典里面的年龄,进行排序
lst=[{'id':3,'name':'taihei','age':18},
{'id':1,'name':'alex','age':28},
{'id':2,'name':'taibai','age':58},
{'id':4,'name':'henhei','age':38}]
# 根据年龄排序
def func(s):
return s['age']
print(sorted(lst, key=lambda dic:dic["age"])) # 根据年龄排序
三、filter() 筛选函数
语法:
filter(function, Iterable)
function: 用来筛选的函数。 在filter中会自动的把Iterable中的元素传递给function,然后根据function
返回的True;则保存,否者,则去掉。
Iterable: 可迭代对象
fe: 根据function返回的True或False,来保存数据
lst = ["渴望", "年轮", "家有儿女", "蜗居", "49天", "浪漫满屋"]
# 把后面的可迭代对象中的每一个元素交给前面的函数。 根据函数返回的True或者False。 判断是否保留该元素
f = filter(lambda s: len(s) > 2, lst)
print("__iter__" in dir(f))
for el in f:
print(el)
lst=[{'id':3,'name':'taihei','age':18},
{'id':1,'name':'alex','age':28},
{'id':2,'name':'taibai','age':58},
{'id':4,'name':'henhei','age':38}]
# 筛选年龄大于等于38的人
print(list(filter(lambda ren: ren['age']>=38, lst)))
四、map() 映射函数
语法:
map(function, Iterable)
对可迭代对象中的每一个元素进行映射,分别执行function操作,返回新的迭代对象,需要变量接收它(新的)
fe: 对旧的可迭代对象,执行function后,全部接收,返回新的
lst = [2, 3, 4 ,5, 6, 7, 1]
# 计算列表中的每一项的平方
# 映射
# 把可迭代对象中的每一个元素拿出来交给前面的函数执行. 保留最后的执行结果
m = map(lambda x: x*x, lst)
for el in m:
print(el)
# 给出一个列表
lst = ["alex_123", "alex_456", "wusir_123", "wusir_456", "alex_789"]
#
# 正确的用户名: alex
# 密码:456
# alex_456
# 第一种方法
print(list(map(lambda s : " yes" if s=="alex_456" else "false" , lst)))
# 第二种方法
print(list(map(lambda s: s.split("_")[0] == 'alex' and s.split("_")[1] == "456",lst)))
五、递归(函数自己调用自己,缺点占内存)
在函数中调用函数本身,就是递归
python中最大的递归深度为1000,但实际操作中不会让你到达1000,
每递归一次就要开辟一片新的一模一样的内存空间,非常占内存,增加了空间复杂度,不能用于复杂的算法
由第三点可以得出,当递归有返回值时,需要写return,传递最终返回值. 否则有可能接收不到返回值(因为函数的返回值是返回给调用者)
fe:遍历文件夹的所有文件,及打印所有文件名(非文件夹的名字)
import os
def func(path, ceng): # path传绝对路径,层用缩进来体现文件夹的所属关系(父子级),
lst = os.listdir(path) # os.listdir(路径) 打开文件夹获取所有的所有内容(所有的文件名含文件夹名字)
for el in lst: # 当前文件夹的所有文件名(包括文件夹名字)
# 拼接真实路径
file_real_path = os.path.join(path, el) # os.path.join(路径, 文件名) 拼接路径和文件名, 使得可以使用这个文件名
if os.path.isdir(file_real_path): # os.path.isdir(拼接好的路径和文件名的变量) 判断是文件夹还是文件
# 递归的入口
print(" " * ceng, el)
func(file_real_path, ceng + 1) # 重复刚才的操作
else: # 不是文件夹,是文件
#递归的出口
print(" " * ceng, el)
func(r"E:a", 0)
5.1 操作系统(os)相关的一些操作
os : 和操作系统相关的一些功能
os.listdir("d:/") 帮我们打开一个文件夹. 返回文件夹内的所有内容(文件的名字)
os.path.join("马化腾","马云") 马化腾/马云
os.path.isdir(路径) 判断这个路径是文件夹还是文件
六、二分法(三种算法)
必须是有序的序列,才能使用二分法
每次能排除一半的数据,效率非常高,局限很大就在要有序的序列
fe: 普通的算法查找一个数
lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963] # 时间复杂度. n
# 让用户输入一个数n. 判断这个n是否出现在lst中
n = int(input("请输入一个数字n:")) # 56
for el in lst:
if n == el:
print('出现了')
break
else:
print("没出现")
fe1: 非递归的二分法,须掌握,面试通常问这个
lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963]
n = int(input("请输入一个数:"))
left = 0 # 左边界
right = len(lst) - 1 # 右边界
while left <= right: # 当左边边界大于右边界的时候,说明不在列表中
mid = (left + right) // 2 # 中间位置的索引
if n > lst[mid]: # n大于中间的数,说明要往mid右边查找
left = mid + 1 # 新的左边界等于mid 向右移一位
elif n < lst[mid]:
right = mid - 1 # 新的右边界等于mid向左移一位
else:
print("存在")
break
else:
print("不存在")
fe2: 递归二分法,方法一:通过改变左右边界查找
lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963]
def binary_search(lst, n, left, right): # 改变的左右边界
if left > right:
return False
mid = (left + right) // 2 # 每次用中间的那个值去判断
if n > lst[mid]:
left = mid + 1
# 当递归有返回值的时候. 需要写return. 否则有可能接收不到返回值
return binary_search(lst, n, left, right) # 此处必须加return, 接收返回值
elif n < lst[mid]:
right = mid - 1
return binary_search(lst, n, left, right) # 此处必须加return, 接收返回值
else:
print("找到了")
return True
n = int(input("请输入一个数字n:")) # 178
ret = binary_search(lst, n, 0, len(lst)-1)
print(ret)
fe3: 二分法,方法二,通过切割列表查找
lst = [4, 56, 178, 253, 625, 1475, 2580, 3574, 15963]
# 切换列表
def binary_search(lst, n):
if len(lst) == 0:
return False
left = 0
right = len(lst) - 1
mid = (left + right) // 2
if n > lst[mid]:
# 当递归有返回值的时候. 需要写return. 否则有可能接收不到返回值
return binary_search(lst[mid+1:], n) # 每判断一次对列表进行切片
elif n < lst[mid]:
return binary_search(lst[:mid], n) # 每判断一次对列表进行切片
else:
print("找到了")
return True
n = int(input("请输入一个数字n:")) # 178
ret = binary_search(lst, n)
print(ret)