一 递归函数
概念:直接或者间接调用自己
必须有一个明确的递归结束条件
# 直接调用
def func():
print('func')
func()
func()
# 间接调用
def func1():
print('func1')
func2()
def func2():
print('func2')
func1()
func1()
python在执行中不会一致递归下去,有一个限制值,一旦超过这个值就会报错,在python中,有方法可以查看和修改这个数值。
import sys
res = sys.getrecursionlimit() # 查看最大递归次数
print(res) # 1000
sys.setrecursionlimit(2000) # 修改递归最大次数
res1 = sys.getrecursionlimit()
print(res1) # 2000
示例:
# 例子
my_list = [1, [2, [3, [4, [5, [6, [7, [8, [9, [10]]]]]]]]]]
# 需求:打印出列表的每个整型
def get_num(my_list):
for i in my_list:
if isinstance(i, int):
print(i)
else:
get_num(i)
get_num(my_list)
二 简单算法
2.1 二分法
需求:如何在一个有序的列表中找到一个值
逻辑思路:取整个列表的中间值,和要找的值进行比较,如果中间值大于要找的值,则舍弃右边的一半,中间值小于要找的值,则舍弃左边的一半,如果相等则找到。
在新的区间重复上述操作,直到越界都没有找到,就是不存在要找的数。
代码实现:
# 题目:有一个有序列表arr,在有序列表中找到target,并返回其索引,找不到返回-1
# 示例
arr = [-2, 4, 6, 9, 13, 45, 77, 99]
target = 45
def dichotomy():
n = len(arr)
# 定义一个区间
left, right = 0, n - 1 # 这是一个左闭右闭区间 也可以写n 只是在判定边界条件和更新左右区间时有所不同
while left <= right: # 因为是一个左闭右闭区间 所以左能等于右 一旦左大于右 则越界 循环结束
mid = left + (right - left) // 2 # 求区间的中间值 防止溢出
if target > arr[mid]: # 说明target在mid的右边
left = mid + 1 # 更新左区间
elif target < arr[mid]: # 说明target在mid的左边
right = mid - 1 # 更新右区间 因为是左闭右闭 所以右区间要-1
elif target == arr[mid]:
return mid
else:
return -1
res = dichotomy()
print(res) # 5
2.2 选择排序
需求:对列表排序
逻辑思路:先取列表的第一个元素,依次和后边的元素进行比较,如果后边的元素小于第一个元素值,则两两交换位置,比较完整个列表,则最小的一个排在了最左边。接着排第二个元素,按照同样的方法可以把第二小的排在第二位。一直排到最后一个的前一位,所有的元素有序。
代码实现:
# 对arr进行排序
arr = [3, 6, 1, 8, 9, 33, -1]
def select_sort():
n = len(arr) # arr长度
for i in range(0, n - 1): # 循环遍历列表中的每一个值
j = i + 1 # 循环出的下一个值的索引位置
while j < n: # 边界条件 j = n时循环结束
if arr[j] < arr[i]: # 如果后面的小于前边的
arr[i], arr[j] = arr[j], arr[i] # 两两交换位置
j += 1 # j每次都自增1 直至越界
return arr
print(select_sort()) # [-1, 1, 3, 6, 8, 9, 33]
2.3 冒泡排序
需求:对列表排序
逻辑思路:两两进行比较,先取第一个和第二个元素,谁大谁在右,在取右边的后下一个比较,谁大谁在右,依次比较到列表的最后一个值,则最大的排到了最右边,再取第一个元素和第二个元素进行比较,谁大谁在右边,取到倒数第二个停止,则第二大的被排到倒数第二位,重复上述操作,直至整个列表有序。
代码实现:
# 对arr进行排序
arr = [3, 6, 1, 8, 9, 33, -1]
def bubble_sort():
n = len(arr)
for i in range(0, n - 1): # 比较次数 一共需要比较n-1次 所以for循环n - 1次结束
for j in range(0, n - 1 - i): # 从第一个元素开始往后比较 排好一个比较的数就少一个
if arr[j] > arr[j + 1]: # 判断前一个元素是否大于后一个元素
arr[j], arr[j + 1] = arr[j + 1], arr[j] # 前大于后则交换位置
return arr
print(bubble_sort()) # [-1, 1, 3, 6, 8, 9, 33]
2.3 插入排序
需求:对列表排序
思维逻辑:索引0位置默认有序,从1位置开始排序,和左边的数据比较,小就交换位置,则1位置也做到有序,2位置开始排序,和左比较,小就左移,2位置做到有序,重复上述步骤,直至所有数据都有序。
代码实现:
# 对arr进行排序
arr = [3, 6, 1, 8, 9, 33, -1]
def insert_sort():
n = len(arr)
for i in range(1, n): # 索引0默认是有序的 直接从1位置开始排序
index = i # 将i位置的数进行排序
while arr[index] < arr[index - 1] and index > 0: # i位置的数和前面已经排好的数进行排序
arr[index], arr[index - 1] = arr[index - 1], arr[index] # 右边小于左边就交换位置
index -= 1 # 下标自减1 直至越界
return arr
print(insert_sort()) # [-1, 1, 3, 6, 8, 9, 33]
练习
1.尝试编写有参函数将多种用户验证方式整合到其中
直接获取用户数据比对
数据来源于列表
数据来源于文件
# 自定义管理员
user_list = ['jasper', '123']
user_dict = {'name': 'tom', 'pwd': '456'}
# 在创建一个user.txt文件 文件里数据为 jack:789
# 直接拿数据比的话名字为lili密码为666才可通过
def outer(condition):
def login_auth(func_name):
def inner(*args, **kwargs):
username = input('username>>>:').strip()
password = input('password>>>:').strip()
# 应该根据用户的需求执行不同的代码
if condition == '直接比':
if username == 'lili' and password == '666':
res = func_name(*args, **kwargs)
return res
else:
print('权限不足')
elif condition == '列表':
if username == user_list[0] and password == user_list[1]:
res = func_name(*args, **kwargs)
return res
else:
print('权限不足')
elif condition == '字典':
if username == user_dict.get('name') and password == user_dict.get('pwd'):
res = func_name(*args, **kwargs)
return res
else:
print('权限不足')
elif condition == '文件':
with open(r'user.txt', mode='r', encoding='utf8') as f:
name, pwd = f.read().split(':')
if username == name and password == pwd:
res = func_name(*args, **kwargs)
return res
else:
print('权限不足')
else:
print('传入的比较方式有误')
return inner
return login_auth
@outer('yyy')
def index():
print('from index')
index()
2.尝试编写递归函数
推导指定某个人的正确年龄 后一个人比前一个小十岁
eg: A B C D E 已知E是18 求A是多少
def get_age(n):
if n == 1:
return 18 # 递归函数结束条件 当n==1时返回e的年龄18
else:
return get_age(n - 1) + 10
res = get_age(5)
# 运行流程
# n = 5 return get_age(4) + 10 58
# n = 4 return get_age(3) + 10 48
# n = 3 return get_age(2) + 10 38
# n = 2 return get_age(1) + 10 28
# n = 1 return 18
print(res) # 58