python基础-二分法、生成式、匿名函数、内置函数
一、算法简介及二分法
1.算法
1.什么是算法
算法是针对专门问题的有效方法,不是所有的算法都很高效
# 算法一直在优化,但是没有最完美的算法
2.二分法
1.二分法的使用要求
待查找的数据集必须有序
2.二分法的缺陷:
针对位置在开头或者结尾的数据,查找效率很低
# 常见算法的原理以及伪代码
# 二分法、冒泡、快拍、插入、堆排、桶排、数据结构(链表 约瑟夫问题 如何链表是否成环
3.通过案例了解二分法的原理
二分法主要是一种查找数据的方法,
1)将待查找的数据按照某种要求分为两部分 # 如:A部分 B部分
2)然后在 这两部分中 判断 数据值在那个部分 # 在A部分中
3)然后重复这个过程,直到找到该数据或者找不到
# 案例
l1 = [12, 21, 32, 43, 56, 76, 87, 98, 123, 321, 453, 565, 678, 754, 812, 987, 1001, 1232]
"""
查找列表中某个数据值
方式1:for循环 次数较多
方式2:二分法
"""
# 代码实现
l1 = [12, 21, 32, 43, 56, 76, 87, 98, 123, 321, 453, 565, 678, 754, 812, 987, 1001, 1232]
# 查找列表中某个数据值
# 方式1:for循环 次数较多
# 方式2:二分法 不断的对数据集做二分切割
'''代码实现二分法'''
# 定义我们想要查找的数据值
# target_num = 987
def get_middle(l1, target_num):
# 添加一个结束条件
if len(l1) == 0:
print('很抱歉 没找到')
return
# 1.获取列表中间索引值
middle_index = len(l1) // 2
# 2.比较目标数据值与中间索引值的大小
if target_num > l1[middle_index]:
# 切片保留列表右边一半
right_l1 = l1[middle_index + 1:]
print(right_l1)
# 针对右边一半的列表继续二分并判断 >>>: 感觉要用递归函数
return get_middle(right_l1, target_num)
elif target_num < l1[middle_index]:
# 切片保留列表左边一半
left_l1 = l1[:middle_index]
print(left_l1)
# 针对左边一半的列表继续二分并判断 >>>: 感觉要用递归函数
return get_middle(left_l1, target_num)
else:
print('恭喜你 找到了!!!')
# get_middle(l1, 987)
# get_middle(l1, 2000)
# get_middle(l1, 12)
l1 = [11, 22, 33, 44, 55, 66, 77, 88, 89, 100, 122, 333, 444]
def get_number(l, target_num):
# 添加结束条件
if len(l) == 0:
print('z找不到该数据')
return
# 1 获取中间的数据值的索引值
middle_index = len(l) // 2
# 2 开始判断
# 3 如果目标数据 > 中间这个数据
if target_num > l[middle_index]:
# 3.1 切片保留右边
r_list = l[middle_index + 1:]
print(r_list)
# 对右边继续使用二分法
return get_number(r_list, target_num)
# 4 如果目标数据 < 中间这个数据
elif target_num < l1[middle_index]:
# 切片保留左边
l_list = l[:middle_index]
print(l_list)
# 对左边继续使用二分法
return get_number(l_list, target_num)
else:
print('找到了')
get_number(l1, 333)
二、三元表达式
1.三元表达式语法
name = input('name')
res = '数据值1' if name == '条件' else '数据值2'
print(res)
""""
数据值1 if 条件 else 数据值2
条件成立则使用数据值1 条件不成立则使用数据值2
"""
2.三元表达式的使用场景
1)一般是 二选一 的情况下使用三元表达式
2)不要使用三元表达式嵌套使用
三、生成式
1.列表生成式
应用场景:需要简化对列表的操作,对列表中对数据,作相同操作
1.列表生成式的语法
new_list = [ 元素 + 操作 for 元素 in old_list]
# 新列表 = [ 元素 和 想对元素进行的操作 for循环取出原列表中元素]
# 案例
new_list =[]
for name in name_list:
data = f'{name}_nb'
new_list.append(data)
print(new_list)
2.列表生成式的应用
1)对列表中对数据,作相同操作,简化代码
new_list = [name + '_nb' for name in name_list]
# 先看for循环 每次for循环之后在看for关键字前面的操作
print(new_list)
2)复杂情况,增加if语句(for循环中 加个 if分支)
new_list = [name + '_nb' for name in name_list if name == 'jason'] # 操作在元素后
new_list = ['_nb' + name for name in name_list if name == 'duoduo']
print(new_list) # 操作在元素前
# 案例
old_list = ['duoduo', 'leethon', 'bo']
new_list = ['大佬:' + name for name in old_list if name == 'leethon']
print(new_list)
2.字典生成式
1.关键字 enumerate(i,start=起始值)
将i中的元素遍历,并按照顺序和递增的起始值 一一组队输出成一个个元组
# 语法
enumerate(i,start=起始值)
i为数据值,type是想判断的数据类型
# 举例
s1 = 'hello world'
for i in enumerate(s1,start=100):
print(i)
----------运行结果--------
(100, 'h')
(101, 'e')
(102, 'l')
(103, 'l')
(104, 'o')
(105, ' ')
(106, 'w')
(107, 'o')
(108, 'r')
(109, 'l')
(110, 'd')
2.字典生成式
1)语法:dict = {i:j for i,j in enumerate('hello world',0)}
2)功能:将字符串'hello world'和起始值0,开始以键值对的形式输入字典
# 举例
s1 = 'hello world'
d1 = {i:j for i,j in enumerate('hello world')}
print(d1)
----------运行结果--------
{0: 'h', 1: 'e', 2: 'l', 3: 'l', 4: 'o', 5: ' ', 6: 'w', 7: 'o', 8: 'r', 9: 'l', 10: 'd'}
3.集合生成式
1.集合生成式
1)语法: {i for i in 数据集}
2)功能: 将 数据集中的元素遍历加入元组中并去重
# 举例
res = {i for i in 'hello'}
print(res)
----------运行结果--------
{'o', 'h', 'l', 'e'}
元组 : 没有元组生成式 下面的结果是生成器
res = ( i + 'sb' for i in 'hello') print(res) ----------运行结果-------- <generator object <genexpr> at 0x102f9d890>
四、匿名函数
1.没有名字的函数 需要使用关键字 lambda
2.语法结构
lambda 形参:返回值
# 匿名函数是不需要写return的,其参数可以有一个也可以有多个
3.使用场景
lambda a,b :a+b
匿名函数一般不单独使用,需要配合其他函数一起使用
五、常见的内置函数
1.map
1.map 函数功能:根据提供的函数对指定序列做映射(如图)
# 相当于一个中间商,为数据的处理提供便捷操作
2.语法结构
map(匿名函数, 数据集)
# 举例
l1 = [1,2,3,4,5]
def func(a):
return a+1
res = map(lambda x:x+1,l1)
print(res)
2.max\min
1.max 函数功能:返回数据中的最大值
2.语法结构: max(数据集) # 返回的是最大值,需要变量名来接收最大值
# 案例1: 数据集是:整型,可以直接比较
l1 = [1,2,3,4,5]
res = max(l1)
print(res)
# 案例2: 数据集是字典,比较时比较的是字典中键值对的键
d1 = {
'zj':123,
'sam':9888,
'sad':999999
}
res = max(d1)
print(res)
-----------运行结果-------------
zj # 字符串的大小如何比较
3.字符串大小
要点:函数 max比较的是字典中的键,键是字符串时,比对的是ASCII码的对应编码的大小
ASCII中 字母对应编码
A-Z 65-96
a-z 97-122
4.函数 max的原理可以看作是for循环
理解 max中,输出的结果还是数据集中的元素,而我们可以指定如何比较数据集中元素的大小
max也就是遍历取值,在字典中取的是关键字key,但是我们可以通过给指定给键排定大小,但是最后输出的还是键key
# 案例
# max底层是for循环
ret = max(d1,key = lambda k:d1.get(k))
print(ret)
# 可以看作是下面的代码简化
def func(a):
return d1.get(a)
rel = max(d1,key = func)
print(rel)
理解 max中,输出的结果还是数据集中的元素,而我们可以指定如何比较数据集中元素的大小
max也就是遍历取值,在字典中取的是关键字key,但是我们可以通过给指定给键排定大小,但是最后输出的还是键key
3.reduce
1.函数reduce功能:传多个值,返回一个值
2.语法结构:需要调用模块之后才能使用
from functools import reduce
reduce()
3.与lambda 联动
# 举例
from functools import reduce
l1 = [11, 22, 33, 44, 55, 66, 77, 88]
res = reduce(lambda a, b: a * b, l1)
print(res)
# 举例
from functools import reduce
l1 = [1,2,3,4,5]
reu = reduce(lambda a,b:a*b,l1)
print(reu)
- *isintance
isinstance(i,type)
i为数据值,type是想判断的数据类型