python-函数使用(三)

递归函数

函数在运行过程中,直接或间接调用了自身

# 官网表示:python默认的最大递归深度为1000次
# import sys
# print(sys.getrecursionlimit())  # 查看当前递归最大深度
# print(sys.setrecursionlimit(2000))  # 修改递归最大深度

# 无限自己调用自己,但是python限制了次数
# 无用递归1:
count = 1
def index():
    global count
    count += 1
    print(count)
    print('from index')
    index()
index()

# 无用递归2:
def func():
    print('from func')
    index()
def index():
    print('from index')
    func()
index()  # 两个函数互相调用

递归使用

1.递推:一层层往下推导,每次往下推会相对于上一次复制度一定要有所下降
2.回溯:依据最后的结论往上推导出最初的答案
3.递归一定要有结束条件
'''
伪代码:可能无法运行,但是可以表述逻辑
'''

# 不打印列表,只打印数字
l1 = [1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,[14,]]]]]]]]]]]]]]
def func1(l1):
    for i in l1:
        if type(i) is int:
            print(i)
        else:
            func1(i)
func1(l1)

# 实现阶乘
def factorial(n):
    if n == 1:
        return 1
    else:
        res = n*factorial(n-1)
        return res

print(factorial(4))  # 24

二分法

# 在列表中查出指定数字
# 第一种方法 直接用for循环从左往右依次查找

# 第二种使用二分法,二分法使用前提数据集必须有序
num = 567
l2 = [1, 11, 23, 43, 44, 57, 68, 76, 81, 99, 123, 222, 321, 432, 444, 567, 666, 712, 899, 999, 1111]

def get_num(num, l2):
    if len(l2) == 0:  # 列表中没有这个数
        return
    sli_num = len(l2) // 2  # 先从中间获取位置索引值
    if num > l2[sli_num]:  # 与列表中间的值做对比
        r_list = l2[sli_num + 1:]  # 如果大于中间值,截取优化右边为新列表
        print(r_list)
        get_num(num, r_list)  # 重新走到这个函数
    elif num < l2[sli_num]:  # 如果小于中间值,目标值就在左边
        l_list = l2[:sli_num]  # 将左边记录为新列表
        print(l_list)
        get_num(num, l_list)  # 继续走到这个函数
    else:
        print(num)  # 刚好等于中间值的情况

get_num(444, l2)

三元表达式

1.当功能需求仅仅是二选一的情况下 那么推荐使用三元表达式
# 常规使用时
def max_num(a, b):
    if a > b:
      return a
    else:
      return b

# 使用三元表达式后
def max_num(a, b):
    return a if a > b else b

# 条件成立抛出if前面的值,否则就抛出else后面的值

2.虽然可以嵌套使用,但是不推荐

# 求三个数最大值
def max_num(a, b, c):
    return a if a > b else (b if b > c else c)

print(max_num(10, 22, 33))

# 案例二
is_free = input("是否收费Y/N:").strip().upper()
res = '收费'if is_free == 'Y' else '免费'
print(res)

# 案例三
username = input("username:").strip()
res = 'NB' if username == 'jason' else 'LB'
print(res)

列表生成式

# 给列表中所有的人名加上_NEW后缀
name_list = ['jason', 'kevin', 'tony', 'jerry']

# 方式一:for循环加字符拼接
new_list = []
for i in name_list:
    new_list.append(i + '_NEW')
print(new_list)


# 方式二:列表生成式
new_list = ['%s_NEW' % i for i in name_list]
print(new_list)

字典生成式

# 将两个列表合成为一个字典
l1 = ['jason', 18, 'read']
l2 = ['name', 'age', 'hobby']

new_dict = {}

for i in range(len(l2)):
    new_dict[l2[i]] = l1[i]
print(new_dict)


name_list = ['jason', 'tony', 'tom']
res = {i: j for i, j in enumerate(name_list, start=1)}

print(res)  # {1: 'jason', 2: 'tony', 3: 'tom'}

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

匿名函数

# 匿名函数:没有名字的函数
'''
语法格式:
    lambda 形参:返回值
'''

# 简单使用
eg1:
a = (lambda x, y: x * y)(5, 6)
print(a)

eg2:
res = [x**2 for x in range(10)]
print(res)

res2 = [(lambda x:x**2)(i) for i in range(10)]
print(res2)

eg3:
print((lambda a, b: a if a > b else b)(10, 11))

# 匿名函数一般不会单独使用,会配合其他函数一起使用
# map() 映射
# 使用 map(function, iterable)
#         函数名,可迭代对象
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
def double(i):
    return i ** 2
print(list(map(double, l)))

print(list(map(lambda x: x ** 2, l)))