递归函数、算法之二分法、三元表达式、各种生成式、匿名函数

一、递归函数

递归函数就是直接或间接调用函数自身的函数,当我们使用这种函数的时候,并不会出现预料之中的死循环,当循环次数达到1000左右就会被解释器强行停止,虽然官方说是1000次,但是当我们使用时,通常会在996次左右停止,但是这种情况下的函数并不算递归函数,递归函数有以下两个条件:

  • 1.直接或者间接调用自己

  • 2.每次调用都必须比上一次简单,并且需要一个明确的结束条件

递推:以层层往下

回溯:基于明确的结果一层层往上

# 伪代码:
"""
age(5) = age(4) + 2
age(4) = age(3) + 2
age(3) = age(2) + 2
age(2) = age(1) + 2
age(1) = 18

age(n) = age(n-1)+2
age(1) = 20
"""


# 真实代码实现
def get_age(n):
    if n==1:
        return 18
    res=get_age(n-1)+2  # age(4)+2
    return res  # age(4)+2

print(age(5))

练习题:

# 利用递归函数依次打印列表中每一个数据值
l1 = [1,[2,[3,[4,[5,[6,[7,[8,]]]]]]]]
# 2.利用递归函数依次打印列表中每一个数据值
l1 = [1,[2,[3,[4,[5,[6,[7,[8,]]]]]]]]
"""
1.for循环l1里面的数据值
2.如果是数字 则打印
3.如果是列表 则循环
4.for循环小列表里面的数据值
5.如果是数字 则打印
6.如果是列表 则循环
7.for循环小小列表里面的数据值
8.如果是数字 则打印
9.如果是列表 则循环
"""
# print(isinstance(123, int))  # 判断第一个数据值是不是属于第二个参数指定的数据类型
# print(isinstance(123, str))  # 判断第一个数据值是不是属于第二个参数指定的数据类型
def get_num(l1):
    for i in l1:  # 递归函数需要结束条件 这里巧在for循环接收到空的能够被for循环的数据时 自动不执行
        if isinstance(i,int):
            print(i)
        else:
            return get_num(i)

get_num(l1)

二、算法简介之二分法

(1)、简介

关于算法我们只需要稍微了解一下就可以了,对于算法,刚入行的小白基本是接触不到相关工作的,除了顶尖高效的相关专业可以直接找到工作.通常情况下需要我们在进入一些公司工作一段时间后,被调到算法部门,才是正常的工作流程,对于算法这个东西,小公司不会成立相关部门研究算法,只有大公司才会成立部门研究算法,因为算法产出低,但是算法从业的工资又偏高,小公司中的算法部门大多数情况都是拿别人的算法来改用的

(2)、什么是算法

算法的范围很大,只要是解决问题的思路都算算法,但是不是所有的算法都是高效的,也有很多不合格的算法,可这并不影响算法的流行,因为算法的应用范围确实很广,几乎涵盖了我们生活中的方方面面,推荐算法(抖音视频推送、淘宝商品推送)、成像算法(AI相关)

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

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

(3)、二分法

二分法是算法中最简单的算法,有很大缺陷,但是面试的时候喜欢拿来考一考

二分法有以下限制条件:

1.进行运算的数据值需要是有序的
2 .运算的时候如果需要取得的数据值是在开头的,反而会更耗时

l1 = [12, 21, 32, 43, 56, 76, 87, 98, 123, 321, 453, 565, 678, 754, 812, 987, 1001, 1232]


# 定义一个想要找的数据值
def get_middle(l1, target_num):
    # 判断目标数据是否在l1列表中
    if len(l1) == 0:
        print('数据不存在')
        return
    # 统计列表中的长度并对半切
    middle_index = len(l1) // 2  # 9
    # 拿到中间的数据
    half = l1[middle_index]  # 321
    # 比较目标数据值大于列表中间数
    if target_num > half:
        # 从列表中间往右切,因为切片操作顾头不顾尾所有进行加一
        right_l1 = l1[middle_index + 1:]  # [453, 565, 678, 754, 812, 987, 1001, 1232]
        # 针对右边一半的列表继续二分并判断 >>>: 感觉要用递归函数
        return get_middle(right_l1, target_num)
    # 比较目标数据值小于列表中间数
    elif target_num < half:
        left_l1 = l1[:middle_index]  # [12, 21, 32, 43, 56, 76, 87, 98, 123]
        # 针对左边一半的列表继续二分并判断 >>>: 感觉要用递归函数
        return get_middle(left_l1, target_num)
    else:
        print('找到了')


get_middle(l1, 12)

三、三元表达式

三元表达式本质

1.是对简单的代码进行缩写,简单的来说就是偷懒的写法减少代码行数

2.三元表达式只适合较为简介的条件判定,较为复杂的判定建议不要用这种方式写代码,因为比较让人难以理解

3.三元表达式不建议嵌套使用,因为三元表达式是为了简化代码,嵌套后反而看着更复杂了

三元表达式语法结构

数据值1 if 条件 else 数据值2
"""
条件成立则使用数据值1 条件不成立则使用数据值2
"""
a = 1
b = 10

c = 10
d = 20
res=a if a > b else (c if c > d else ( 'bbb' if d > c else 'aaa'))
print(res)

# is_beautiful=True
# res = '漂亮' if is_beautiful else '不漂亮'
# print(res)

cmd = input('请选择是否输入:(y/n)')
res='继续' if cmd == 'y' else '不继续'
print(res)

四、各种生成式

生成式总共有三种:列表生成式、字典生成式、集合生成式、集合生成式、元组没有生成式,元组类型叫生成器,会生成一个类似工厂的东西,不会直接生成列表

生成式的作用:用于对数据类型中的所有数据值进行相同操作

表现形式:

new_list = [name + "_NB" for name in name_list]

左边是变量名绑定修改后的结果,右边最外层的是最后生成数据的类型,通常来说我们都是用的什么生成器就在外层使用什么类型对应的外层符号。内层for循环左边的代码是规定进行的操作,for循环的作用就是一个个取值进行修改,因为外层套着框,所以修改后的值就依次保存在列表中了,如果是字典和集合的话因为本身的无序性,输出结果的时候可能会没有顺序。
列表生成式

name_list = ['jason', 'kevin', 'oscar', 'tony', 'jerry']
# 给列表中所有人名的后面加上_NB的后缀
# for循环
new_list = []
for name in name_list:
    data = f'{name}_NB'
    new_list.append(data)
print(new_list)
# 列表生成式
# 先看for循环 每次for循环之后再看for关键字前面的操作
new_list = [name + "_NB" for name in name_list]
print(new_list)
# 复杂情况
new_list = [name + "_NB" for name in name_list if name == 'jason']
print(new_list)
new_list = ['大佬' if name == 'jason' else '小赤佬' for name in name_list if name != 'jack']
print(new_list)

字典生成式

# 字典生成式
s1 = 'hello world'
for i,j in enumerate(s1,start=100):
    print(i,j)
d1 = {i: j for i, j in enumerate('hello')}
print(d1)

注:这里的i和j相当于进行了解压赋值操作,如果这里只有一个变量名,就等于绑定了一对键值对,这时候输出的值就键值对,两个变量的时候就是分别输出键和值。
enumerate方法是给输出的值输出一个序号,可以自己设置起点的值

元组生成器(稍微介绍一下区别)
形式跟生成式差不多但是功能不一样

# 元组生成式>>>:没有元组生成式 下列的结果是生成器(后面讲)
res = (i+'SB' for i in 'hello')
print(res)
for i in res:
    print(i)

五、匿名函数

# 没有名字的函数
def index():
    pass

index()
"""
语法格式:
    lambda 形参:返回值
    lambda x:x**2

匿名函数一般步单独使用,会配合其他函数使用
    map()
"""
# def index(x):
#     return x ** 2

# res=lambda x:x**2  # 内存地址
# print(res(2))
# # print(index(3))
#
# print(index)
# print(res)


l = [1,2,3,4,5,6,7,8,9]
# def index(x):
#     return x**2

# res=list(map(index, l))  # <map object at 0x0000017D935721F0>
res=list(map(lambda x:x**2, l))  # <map object at 0x0000017D935721F0>
print(res) # [1, 4, 9, 16, 25, 36, 49, 64, 81]

posted @   吴仁耀  阅读(86)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
  1. 1 原来你也在这里 周笔畅
  2. 2 世间美好与你环环相扣 柏松
  3. 3 起风了 吴青峰
  4. 4 极恶都市 夏日入侵企划
世间美好与你环环相扣 - 柏松
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 尹初七

作曲 : 柏松

编曲 : 彭圣杰

偏偏秉烛夜游

偏偏秉烛夜游

午夜星辰 似奔走之友

爱你每个结痂伤口

酿成的陈年烈酒

入喉尚算可口

入喉尚算可口

怎么泪水 还偶尔失守

邀你细看心中缺口

裂缝中留存 温柔

此时已莺飞草长 爱的人正在路上

此时已莺飞草长 爱的人正在路上

我知他风雨兼程 途经日暮不赏

穿越人海 只为与你相拥

此刻已皓月当空 爱的人手捧星光

我知他乘风破浪 去了黑暗一趟

感同身受 给你救赎热望

知道你不能 还要你感受

知道你不能 还要你感受

让星光加了一点彩虹

让樱花偷偷 吻你额头

让世间美好 与你环环相扣

此时已莺飞草长 爱的人正在路上

此时已莺飞草长 爱的人正在路上

我知他风雨兼程 途经日暮不赏

穿越人海 只为与你相拥

此刻已皓月当空 爱的人手捧星光

我知他乘风破浪 去了黑暗一趟

感同身受 给你救赎热望

此时已莺飞草长 爱的人正在路上

此时已莺飞草长 爱的人正在路上

我知他风雨兼程 途经日暮不赏

穿越人海 只为与你相拥

此刻已皓月当空 爱的人手捧星光

我知他乘风破浪 去了黑暗一趟

感同身受 给你救赎热望

知道你不能 还要你感受

知道你不能 还要你感受

让星光加了一点彩虹

当樱花开的纷纷扬扬

当世间美好 与你环环相扣

特别鸣谢:槿葵,我们的海报制作妹妹。

原唱:柏松

吉他:柏松

和声:柏松

录音:柏松

混音:张强

点击右上角即可分享
微信分享提示