递归函数、算法及生成式


一.递归函数

  递归:函数在运行过程中直接或间接的调用了自身   

count = 1
def index():
    global count
    count += 1
    print(count)
    print('from index')
    index()
index()  

    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

def get_age(n):
    if n == 1:
       return 18
    return get_age(n - 1) + 2
print(get_age(5))

  练习:打印出列表l里的每一个数字(不能打印列表) 

    思路:

    1.循环该列表 获取列表内每一个元素
    2.判断该元素是否是数字 如果是数字 则直接打印
    3.如果是列表 则循环该列表 获取列表内每一个元素
    4.判断该元素是否是数字 如果是数字 则直接打印
    5.如果是列表 则循环该列表 获取列表内每一个元素
    6.判断该元素是否是数字 如果是数字 则直接打印
    7.如果是列表 则循环该列表 获取列表内每一个元素

def get_num(l):
    for i in l:
        if type(i) is int:
            print(i)
        else:
            # 也是for循环 然后判断
            get_num(i)
get_num(l)

# for循环空列表会不执行(结束条件)

二. 算法之二分法

  1.什么是算法:解决问题的高效方法

  2.二分法:

    二分法能够使用的场景,数据集必须有序

l = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
def my_partner(target_num, l):  # target_num=321  l=l
    if len(l) == 0:
        print('不存在')
        return
    # 先获取中间位置索引值
    middle_index = len(l) // 2  # 8
    # 判断中间索引对应的值比目标值大还是小
    if target_num > l[middle_index]:
        # 说明要找的元素只可能出现在列表的右侧
        l_right = l[middle_index + 1:]  # l[9:]
        print(l_right)
        my_partner(target_num, l_right)
    elif target_num < l[middle_index]:
        # 说明要找的元素只可能出现在列表的左侧
        l_left = l[:middle_index]
        print(l_left)
        my_partner(target_num, l_left)
    else:
        print('找到了', target_num)
my_partner(11, l)  # 要查找的元素在开头  那么还没有依次查找的效率高

三. 三元表达式

   当功能需求仅仅是二选一的情况下 推荐使用三元表达式

   条件成立采用if前面的值 if 条件 else 条件不成立采用else后面的值

   三元表达式尽量不要嵌套使用

def my_max(a, b):
    return a if a > b else b

# 可以嵌套但不推荐使用
res = '可以' if 10 > 2 else ('不可以' if 2 >5 else '不知道')
print(res)

四. 列表生成式

name_list = ['jason', 'kevin', 'tony', 'jerry']
# 给列表中所有的人名加上_DSB后缀
'''传统做法'''
# 1.定义一个空列表
new_list = []
# 2.for循环老列表
for name in name_list:
# 3.生成新的名字
new_name = '%s_DSB'%name
# 4.添加到新的列表中
new_list.append(new_name)
print(new_list)
'''列表生成式'''
res = ['%s_DSB' % name for name in name_list]
print(res)

'''传统做法'''
# 1.定义一个空列表
new_list = []
# 2.for循环老列表
for name in name_list:
    # 3.生成新的名字
    if name == 'jason':
        continue
    else:
        new_name = '%s_DSB'%name
        # 4.添加到新的列表中
        new_list.append(new_name)
print(new_list)
'''列表生成式'''
res = ['%s_DSB' % name for name in name_list if name != 'jason']
print(res)

五. 字典生成式

l1 = ['name', 'age', 'hobby']
l2 = ['jason', 18, 'read']
new_dict = {}
for i in range(len(l1)):
    new_dict[l1[i]] = l2[i]
print(new_dict)

  enumerate()
  针对该方法使用for循环取值 每次会产生两个结果
    第一个是从0开始的数字
    第二个是被循环对象里面的元素
  还可以通过start参数控制起始位置  

    for i, j in enumerate(l1, start=1):
    print(i, j)

name_list = ['jason', 'kevin', 'tony', 'jerry']
res = {i: j for i, j in enumerate(name_list) if j != 'jason'}
print(res)

res1 = {i for i,j in enumerate(name_list)}
print(res1,type(res1))

六. 匿名函数

  没有名字的函数

  语法格式

    lambda  形参:返回值

print(lambda x:x**2)
def index():
    pass
print(index)
print((lambda x: x ** 2)(2))
res = lambda x: x ** 2
print(res(2))

'''匿名函数一般不会单独使用 都是配合其他函数一起使用'''
map()  映射
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
def index(n):
    return n ** 2
print(list(map(lambda x:x**2, l)))

相关