递归函数以及其他了解知识

发布时间 2023-06-01 21:07:12作者: Way*yy

递归函数

什么是递归函数?
'''递归就是直接或者间接使用自己的函数就是递归函数,执行递归函数将反复调用其自身,每调用一次就进入新的一层,当最内层的函数执行完毕后,再一层一层地由里到外退出。'''

递归函数分为两个阶段:
1、递推:由外向内的一个过程
2、回溯:从内向外的一个过程

# 练习题:
l = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13]]]]]]]]]]]]]
# 给打印出列表中的所有元素值,只打印除列表之外的元素,如果是列表不打印
"""
    循环打印:
    1. 判断元素是不是列表,如果是列表不打印,如果不是列表则打印
    2. 继续判断,元素是不是列表,如果不是则打印,如果是,不在打印
    3. 继续循环,判断元素是不是列表,如果不是,则打印,如果是,不打印
    4. 继续循环...
"""


# for i in l:
#     # 判断是不是列表
#     if type(i) is int:
#         print(i)
#     else:
#         # 说明是列表
#         # 继续循环
#         for j in i:
#             # 判断j是不是列表
#             if type(j) is int:
#                 print(j)
#             else:
#                 # 说明是列表
#                 # 继续循环
#                 for k in j:
#                     # 判断k是不是列表
#                     if type(k) is int:
#                         print(k)
#                     else:
#                         ...

# 使用递归函数:

def get_num(l):
    for i in l:
        if type(i) is int:
            print(i)
        else:
            get_num(i)


get_num(l)

算法之二分法

什么是二分法?
'''
二分法:也称折半搜索、对数搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。
'''
# 二分查找法
l = [2, 3, 11, 23, 34, 44, 45, 55, 56, 66, 67, 77, 88, 99, 100]

# 在列表中找66是否有
1. for循环遍历
for i in l:
    if i == 66:
        print("找到了")
        # for 循环确实可以做到但是需要一直遍历到66的位置才可以找到
        
2. 二分法实现
	'''算法不一定都是比其他方法高效的'''
    
l = [11, 2, 3, 44, 55, 66, 77, 88, 99, 100, 23, 34, 45, 56, 67,101]
l.sort()  # 对列表进行排序
print(l)
print(len(l))
digit = 66  # 定义一个目标数据


def index(digit, l):
    if len(l) == 0:  # 判断列表是否为空
        print('没有要查找的信息')
        return
    midfill = len(l) // 2  # 对列表长度进行整除,找到中间值
    if digit > l[midfill]:  # 说明目标数据在列表右边
        l_digit = l[midfill + 1:]
        print(l_digit)
        index(digit, l_digit)
    elif digit < l[midfill]:  # 说明目标顺序在列表左边
        l_digits = l[:midfill]
        print(l_digits)
        index(digit, l_digits)
    else:
        print('找到了')


index(digit, l)


# 冒泡排序、快排、插入等

三元表达式

# 三元表达式
def index(a, b):
    if a > b:
        return a
    else:
        return b


print(index(1, 2)) # 2


# 简化版
def index(a, b):
    return a if a > b else b


res = index(3, 4)
print(res) # 4
"""
	语法结构:
		条件成立返回if前面的值 if 条件 else 条件不成立返回else后面的值
    
"""

"""三元表达式的使用场景:只有当需求功能是二选一的情况下,才使用三元表达式"""

# res = '干饭' if 2 > 1 else '不干饭'
# print(res)

# res1 = '明天出去玩' if True else '在家学习'
# print(res1)


# cmd = input('请问你是否喜欢学习:(y/n)')
# if cmd == 'y':
#     print('学习使我快乐')
# else:
#     print('天天就知道学习')

# res = '学习使我快乐' if cmd == 'y' else '天天就知道学习'
# print(res)

# 他还可以支持嵌套
is_beautiful = True
res = '干饭' if 1 > 2 else '学习' if False else '喜欢' if is_beautiful == True else '不喜欢'
print(res)

"""
    一般情况我们在写代码的时候,尽量不要使用嵌套的情况
    但是,嵌套的是一般出现在面试题里面
"""

列表生成式

name_list = ['kevin', 'tank', 'tony', 'jerry']
# 1. 给列表中的所以名称加一个后缀_DSB
# 2. 定义一个空列表用来存储拼接之后的值
new_name_list = []

# 3. 循环列表
for name in name_list:
    # res = '%s_DBS' % name
    # res = name +'_DSB'
    new_name_list.append('%s_DBS' % name)

print(new_name_list)

# 列表生成式
res = [name+'_DSB' for name in name_list]
print(res)

# 2. 定义一个空列表用来存储拼接之后的值
new_name_list = []

name_list = ['kevin', 'tank', 'tony', 'jerry']

# 2.1、 给列表中的所有名称都加一个后缀_DSB, 除了jerry不加
for name in name_list:
    if name != 'jerry':
        new_name_list.append('%s_DSB' % name)

print(new_name_list)

# 列表生成式
# res = ['%s_DSB' % name for name in name_list if name != 'jerry']
res = ['%s_DSB' % name if name != 'jerry' else name  for name in name_list]
print(res)

其他生成式(了解)

l = ['name', 'age', 'gender']
l1 = ['kevin', 18, 'male']

# 组织成:{'name':'kevin', 'age':18, 'gender':'male'}
# 1. 定义一个空字典
new_dict = {}
for i in range(3):
    new_dict[l[i]] = l1[i]
print(new_dict)  # {'name': 'kevin', 'age': 18, 'gender': 'male'}

"""
补充一个方法:enumerate
    1. 循环enumerate方法可以得到两个值
        索引、元素
    
"""
for i, j in enumerate(l, start=2):
    print(i, j)

# 字典生成式
res = {i: j for i, j in enumerate(l) if j != 'name'}
print(res)

# 集合生成式
res = {i for i, j in enumerate(l)}
print(res)

# 元组
res1 = (i for i in enumerate(l))  # 生成器
print(res1)

匿名函数

"""没有名字的函数"""
之前使用def关键字定义的函数都是有名函数,有名字的函数

"""
语法格式:
	lambda 形参:返回值
"""

res1 = lambda x: x + 1
print(res1(2))  # 3


def index(x):
    return x + 1


print(index(1))  # 2

res = lambda x: x + 1
res(1)
print(res(1))  # 2
print((lambda x: x + 1)(2))  # 3

匿名函数的内置方法

# 有什么使用场景:他一般不会单独使用,会配合几个常见的内置函数使用

############## map()

l = [1, 2, 3, 4, 5, 6]

def index(x):
    return x + 1

res = map(index, l)  # 底层就是for循环
print(list(res))  # [2, 3, 4, 5, 6, 7]

# 使用匿名函数
res = map(lambda x:x+1, l)  # 底层就是for循环
print(list(res))  # [2, 3, 4, 5, 6, 7]

############## zip()


l1 = [1, 2, 3, 4, ]
l2 = ['a', 'b', 'c', 'd']
lst = []
for i in range(len(l1)):
    lst.append((l1[i], l2[i]))

print(lst) #[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]

# 匿名函数

l1 = [1, 2, 3, 4, ]
l2 = ['a', 'b', 'c', 'd']
l3 = ['aa', 'bb', 'cc','dd']
l4 = ['aaa', 'bbb', 'ccc', 'ddd', 'eee']
res=zip(l1, l2, l3, l4)  # 拉链 # [(1, 'a', 'aa', 'aaa'), (2, 'b', 'bb', 'bbb'), (3, 'c', 'cc', 'ccc'), (4, 'd', 'dd', 'ddd')]
print(list(res))

############## max min

l1 = [1, 2, 3, 4, 5]
print(max(l1))  # 5
print(min(l1))  # 1
s = ['kevin', 'tank', 'jerry']
print(max(s))  # tank

d = {
    'kevin': 2000,
    'tank': 1000,
    'oscar': 300000,
}
print(max(d)) # tank
# 如果想比较字典v值的大小该如何比较呢?

d = {
    'kevin': 2000,
    'tank': 1000,
    'oscar': 300000,
}

def index(key):
    return d[key]


print(max(d, key=index))  # oscar
print(min(d, key=lambda key: d[key]))  # tank

# 这时候就是比较v值的大小了

############## filter 过滤

ll = [11, 22, 33, 44, 55]
ls = []
for i in ll:
    if i > 30:
        ls.append(i)
print(ls)

# 匿名函数:
res = filter(lambda key: key > 30, ll)
print(list(res))