# 全局变量
a =10
b =20defx():# global 关键字声明函数 x 内部使用全局变量 aglobal a
a =100# 修改了全局变量# 定义一个局部变量 b, 这个和全局变量不冲突, 当函数执行完成后会销毁
b =200defy():# nonlocal 关键字声明函数 y 内部使用局部变量 bnonlocal b
b =2000# 修改了局部变量# 调用内部的方法
y()# 将 a, b 返回, 验证结果return a, b
if __name__ =="__main__":print(x())#(100, 2000)
高级用法
闭包和验证闭包
"""
内层函数对外层函数的非全局变量进行引用, 就是闭包
可以使用 __closeure__ 进行判断, 如果是, 则返回一个内存地址, 如果不是, 则返回为空
"""deffunc_outside():# 这个是外层函数的非全局变量
x =10# 这个就是内层函数deffunc_inside():# 这里对外层变量 x 进行引用, 不需要做任何操作nonlocal x
# 执行内层函数
b()# 通过__closure__方法判断print(b.__closure__)if __name__ =="__main__":
a()# 结果是一个内存地址, 所以它是闭包
lambda 表达式(匿名函数)
"""
用于定义简单的函数逻辑
多配合其他函数使用
lambda 函数的语法示例:
lambda i: i * 2
lambda i: True if i % 2 == 0 else False
"""# 定义 lambda 表达式
r =lambda x: x*2# 执行函数, 正常传参
r(2)# 配合其他函数使用, https://blog.csdn.net/yang_kaiyue/article/details/80068208 也有示例
r =filter(lambda x:Falseif x %2==0elseTrue)print(list(r))
递归函数
定义
递归调用, 在调用一个函数的过程中, 直接或间接的调用函数本身, 称之为递归调用
递归的必备两个阶段: 1. 递推 2. 回溯
python 中没有尾递归优化, 又占资源, 所以 python 的递归效率低
递归需要有明确的结束
示例
"""
常用于反推和递推的模型
反推: 已知最后一个的信息, 反推第一个的信息
递推: 从第一个一直向后, 直到满足条件
内部一定有一个 if 判断, 用于结束递归
"""# 1. 第一个人比第二个人大 2 岁, 第二个人比第三个人大 2 岁, 第三个人 18 岁, 问第一个人多大# 参数理解为总数(递归深度)deffuncA(n):# n 为 1 时, 拿到最后一个的确切信息, 并返回if n ==1:return18# 需要回溯(根据下层数据计算上层数据), 需要 return# 调用本身, 深度-1,并且处理不同深度的数据差异else:return funcA(n-1)+2print(funcA(3))# 2. 依次打印所有元素
l =[1,[2,[3,[4,[5,[6,7]]]]]]deffuncB(l):for i in l:iftype(i)==list:
funcB(i)else:print(i)
funcB(l)
高级应用
三级菜单
"""
省/市 -> 区 -> 地名 -> 公司名
"""
menu ={'北京':{'海淀':{'五道口':['soho','网易','google'],},'朝阳':{'国贸':[],},'东城':{},},'山东':{},}defchoose_menu(d):# 判断是否在无法展开的子菜单(因为只有最末端为 list 类型)iftype(d)==list:print("查询结果为 %s"%str(list(d)))else:# 展示菜单for i in d:print(i, end=" ")# 拿到查询选项
k =input("input: ")# 判断如果选项在菜单中, 且菜单内容不为空if k in d andlen(d[k])!=0:
choose_menu(d[k])else:print("查询结果为空")
choose_menu(menu)
二分查找算法
deffind_num(l, num, start=0, end=None):# 因为是有序算法, 先确定边界if num < l[0]or num > l[-1]:return"超出有序数列范围"# 如果未传start和end参数, 则设置为整个列表ifnot end:
end =len(l)# 如果索引是相邻的且起始位置不为0, 那么可以判定这个数字不在数列中if end-start ==1and start !=0:return"找不到这个数字"# 计算中间值
mid =(start+end)//2if num == l[mid]:return mid
elif num > l[mid]:return find_num(l,num,mid,end)elif num < l[mid]:return find_num(l,num,start,mid)
l =[10,20]# 找 10 在列表l中的索引print(find_num(l,10))