算法简介之二分法,常见表达式与推导式

一.算法简介及二分法

1.算法简介

  • 1.什么是算法

    算法就是解决问题的有效方法 不是所有的算法都很高效也有不合格的算法

  • 2.算法的应用场景

    推荐算法(抖音视频推送 淘宝商品推送)

    成像算法(AI相关)

    几乎涵盖了我们日常生活中的方方面面

  • 3.了解

    ​ 算法工程师待遇很好,但是要求非常高(学历,经验等)。而且也不是所有的互联网公司都养得起算法部门,只有一些大型互联网公司才有,比如腾讯,阿里。

    ​ 算法部门类似于药品研发,可能很长时间才能有所成果,投资成本过大。

2.二分法

  • 引入

    ​ 二分法是算法中最简单的算法 甚至都称不上是算法

    二分法使用要求:

    ​ 待查找的数据集必须有序

    二分法的缺陷:

    ​ 针对开头结尾的数据 查找的数据集必须有序

    常见算法的原理以及伪代码

    ​ 二分法、冒泡、快拍、插入、堆排、桶排、数据结构(链表 约瑟夫问题 如何链表是否成环)

  • 实操

    l1 = [1, 3, 5, 7, 9, 111, 222, 333, 444, 555, 666, 777, 888, 999, 1111, 2222, 3333]
    '''查找列表中某个数据值'''
    '''方式1:for循环 次数较多'''
    '''方式2:二分法 不断的对数据集做二分切割'''
    代码实现:
    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, 888) 
    """
    结果:
    [555, 666, 777, 888, 999, 1111, 2222, 3333]
    [555, 666, 777, 888]
    [888]
    找到了
    """
    get_middle(l1, 1)
    """
    结果:
    [1, 3, 5, 7, 9, 111, 222, 333]
    [1, 3, 5, 7]
    [1, 3]
    [1]
    找到了
    """
    get_middle(l1, 3333)  
    """
    结果:
    [555, 666, 777, 888, 999, 1111, 2222, 3333]
    [1111, 2222, 3333]
    [3333]
    找到了
    
    """
    
    
    

二.表达式与推导式

1.三元表达式

  • 定义

    res = 条件成立返回值 if 条件 else 条件不成立返回值
    
  • 使用

    '''简化步骤:代码简单且只有一行,那么可以直接在冒号后面编写'''
    name = 'jason'
    if name == 'jason':print('老师')
    else:print('学生')
    
    三元表达式:
    res = '老师' if name == 'jason' else '学生'
     print(res)
    
    
  • 补充

    三元表达式一般只用于二选一的情况 使用三元表达式较为简单,并且不推荐多个三元表达式嵌套

2.列表生成式

  • 定义

    res = [表达式 for 变量名 in 循环对象]
    复杂式
    res = [表达式 for 变量名 in 循环对象 if 条件]
    
  • 使用

    # 需求:将列表中所有的人名后面加上_NB的后缀
    name_list = ['jason', 'kevin', 'tony', 'oscar', 'tom']
    # for循环
    new_list = []
    for name in name_list:
        data = f'[name]_NB'
        new_list.append(data)
    print(new_list)  # ['jason_NB', 'kevin_NB', 'tony_NB', 'oscar_NB', 'tom_NB']
    # 列表生成式
    new_list = [name+'_NB' for name in name_list] 
    print(new_list)  # ['jason_NB', 'kevin_NB', 'tony_NB', 'oscar_NB', 'tom_NB']
    # 复杂情况
    new_list = [name+'_NB' for name in name_list if name == 'jason']
    print(new_list)  # ['jason_NB']
    new_list = [name='_NB' for name in name_list if name != 'jason']
    print(new_list)  # ['kevin_NB', 'tony_NB', 'oscar_NB', 'tom_NB']
    
  • 补充

    列表生成式中值允许出现for 和 if 不能出现else 因为会产生歧义(for和if都能结合else)

3.字典生成式

  • 定义

    res = {key: value for 变量名 in 循环对象}
    复杂式
    res = {key: value for 变量名 in循环对象 if 条件}
    
  • 使用

    # 用for循环遍历
    s1 = 'hello word'
    for i, j in enumerate(s1, start = 100):  # enumerate关键字的作用是将数据类型中的所有数据值打上编号,这段代码的意思是将字符串中的每个字符都关联相应的编号
        print(i, j)  # 输出所有编号与字符的组合
    # 字典生成式
    d1 = {i: j for i, j in enumerate('hello')}
    print(d1)  # {0: 'h', 1: 'e', 2: 'l', 3: 'l', 4: 'o'}
    

4.集合生成式

  • 定义

    res = {表达式 for 变量名 in 循环对象}
    复杂式
    res = {表达式 for 变量名 in 循环对象 if 条件}
    
  • 使用

    res = {i for i in 'hello'}
    # 遍历字符串中的字符,然后将遍历出的字符作为数据值存放到新的集合
    print(res)
    

5.补充

​ 没有元组生成式

三.匿名函数与常用内置函数

1.匿名函数

没有名字的函数 需要使用关键字lambda

语法结构:
	lambda 形参:返回值
使用场景:
    lambda a, b:a + b
匿名函数一般不单独使用 需要配合其他函数一起用

2.常用内置函数

1.map() 映射

l1 = [1, 2, 3, 4, 5]
# def func(a):
	# return a + 1
# 当我们使用定义函数的方式实现列表中每个数据加1的需求时
res = map(lambda x:x+1, l1)  # map关键字的使用
print(list(res))  # 相当于将l1中的每个数据取出来,经过匿名函数处理后,映射出处理后的数据

2.max()\min()

l1 = [11, 22, 33, 44]
res = max(l1)
# max()的作用是找出列表数据中的最大值,min()的作用是找出列表数据中的最小值
d1 = {
    'zj': 100, 
    'jason': 8888, 
    'berk': 9999999, 
    'oscar': 1
}
def func(a):
    return d1.get(a)
res = max(d1, key=lambda k:d1.get(k))
res = max(d1, key=func)
print(res)
"""当max()或者min()对字典使用时,如果只是用关键字与字典名的话,那么只会根据字典的K键进行取值比对,而在字符编码中A-Z对应65-90,a-z对应97-122,所以如果直接使用max(d1),得到的结果是zj,因为在这个过程中只有字典的键参与,而z对应可了最大值,而在语法结构中,max()括号中除了变量名之外,还可以指定一个key"""
max(d1, key=func),这段代码中,key的作用就是调用函数取出每个键所对应的值作为max取最大值的依据,但是最后得到的结果仍然是键,而不是数据值

3.reduce

from functools import reduce
    l1 = [11, 22, 33, 44, 55, 66, 77, 88]
    res = reduce(lambda a, b: a + b, l1)
    # reduce(匿名函数, 列表名)
    print(res)
# reduce的使用需要调用模块,它的作用是去除列表中的每个数据值,经过临时函数处理后,得到所有数据值的总和
posted @ 2022-10-13 18:28  dear丹  阅读(155)  评论(0编辑  收藏  举报