Day 5-变量与高阶函数
1.全局变量与局部变量
如果函数的内容无global关键字,优先读取局部变量,能读取全局变量,无法对全局变量重新赋值 NAME=’’ #但对于可变类型,可以对内部元素进行操作
如果函数中有global关键字,变量实质上就是全局的那个变量,可读取可赋值
name='chris' def test(): name='joe' print(name) test() print(name)
此时输出的是:joe chris 全局变量未被修改(只能读取,无法重新赋值,只能设置局部变量),若要修改,在函数里加入global
name='chris' def test(): global name name='joe' print(name) test() print(name)
此时输出就是:joe joe
#但可以对全局变量进行增加(如全局变量是列表时)
name=['chris',2] def test(): name.append(6) print(name) test()
此时输出值为['chris', 2, 6]
规范:全局变量尽量大写,局部变量尽量小写
#
name='蔡晓武' def a(): name='啊武' def b(): global name name='帅哥' b() print(name) print(name) a() print(name)
此时输出的是:
蔡晓武
啊武
帅哥
global改变的不是a()里的name
name='蔡晓武' def a(): name='啊武' def b(): nonlocal name name='帅哥' b() print(name) print(name) a() print(name)
nonlocal指的是改变上级变量,此时输出值为:
蔡晓武
帅哥
蔡晓武
2.前向引用
函数即变量
#程序优先找自己缩进的作用域
3.递归(自己调用自己)
特性:
1.必须要有一个明确的结束条件
2.没次进入更深一层的递归时,问题规模相比上次递归都有减少
3.递归的效率不高,递归层次过多会导致栈溢出
4.匿名函数
Lambda x:x+1 X相当于形参
a=lanmbda x:x+1
print(a(10)) 此时得出的值就是11
def change(x):
return name+’_shy
正常函数和匿名函数的区别:
name = 'chris' def change_2(x): return x+'_sb' res = change_2(name) print(res) f = lambda x:x+'_sb' print(f(name)) b=lambda x,y,z:(x+3,y+2,z+2) print(b(2,3,4))
5.三种编程方法论
(1)面向过程:找到解决问题的入口,按照一个固定的流程去模拟解决问题的流程
(2)函数式=编程语言定义的函数+数学意义的函数
特征:1.不可变:不用变量保存状态,不修改变量
6.尾调用:在函数的最后一步调用另外一个函数(最后一行不一定是函数的最后一步)
以下这个就不是尾调用:因为最后一步是+1,而不是先进行递归
def bar(n): return n def foo(x): return bar(x)+1
高阶函数:1.函数接收的参数是一个函数名 2.返回值包含函数
(3)面向对象
7.高阶函数调用实现(map函数),处理序列中的每个元素,得到的结果是一个列表,该列表元素个数及位置与原来一样
a = [2,3,4,6,7] def add_one(x): return x+1 def map_1(y,z): #y就是函数名 b=[] for i in a: c=y(i) #重点!!!! b.append(c) return b print(map_1(add_one,a)) print(map_1(lambda x:x+1,a))
此时输出为[3, 4, 5, 7, 8]
等同于:
a = [2,3,4,6,7] t=map(lambda x:x+1,a) print(list(t))
map函数的第一个参数为一个功能函数既处理逻辑,第二个对象为可迭代对象
map功能就是将第二个参数for循环进入到第一个参数的逻辑中,既对一个列表的数据进行加工
8.filter函数,对一组数进行筛选渗透,既遍历序列中的每个元素,判断每个元素得到布尔值,如果是True则留下来
a=['chris_sb','alex','allen'] print(list(filter(lambda x: x.endswith('sb'),a)))
既让第二个参数进行for循环使其执行第一个参数的逻辑,如果为真,则保留该值
9.reduce函数,合并一个序列,最终压缩成一个值
让列表内的函数相乘
a=[2,3,6] def test(func,array,init=None): if init==None: res=a.pop(0) else: res=init for i in array: res=func(i,res) return res from functools import reduce print(reduce(lambda x,y:x*y,a,2))
10.内置函数
(1)绝对值
print(abs(-1))
(2)布尔运算all()
Print(all(1,’2’))此时为True
若存在空或者0,则为False,若为空则是True- print(all(‘’))
(3)any()有一个值为真就是真
(4)bin()把十进制改成二进制
(5)bool() 为False 的情况 – 空 None 0 的布尔值为False
(6)bytes()把字符改成字节 print(bytes(‘你好’,encoding=’utf-8’,decode(‘utf-8’))) decode 为解码 !!!用什么编码就用什么解码 另一种编码解码 gbk
(7)dir(all()) 打印某个对象下面用了什么方法
(8)divmod(10,3) 得到值(3,1) 做除法得到商和余数
(9)eval()1.把字符串的数据结构提取出来
a={‘name’:’chris’}
b=eval(a)
print(b[‘name’]) 输出值为chris
2.eval()能把字符串里的数字运算结果求出来如 eval(‘2-1*3’)
(10)hash() ##可hash的数据类型既不可变数据类型,不可hash的数据类型既可变类型 每个值hash后都有一个hash值
(11)help()查看某个函数怎么用
(12)hex()十进制转十六进制
(13)oct()十进制转八进制
(14)instance() 看该实例是否是对象的实例 print(instance(‘hello’,int)) 此时输出为false
(15)globals()全局变量
(16)locals()局部变量
(17)max() min()只要是可迭代的数据类型,就可以比较 取最大最小值 a=[1,3,5] print(max(a)) 值为5
(18)zip()拉链 使两个参数一一对应,左右两个参数多少都无无所谓,遵循一一对应,组成一个新的数据类型,一一对应
print(list(zip(('a','b','c'),(4,5,6))))
#此时输出值为[('a', 4), ('b', 5), ('c', 6)]
字典中一一对应的序列实现
p={'a':2,'b':3,'c':6} print(list(zip(p.keys(),p.values())))
此时输出值为[('a', 2), ('b', 3), ('c', 6)]
字符串中
print(list(zip('hello','asdff')))
此时输出值为[('h', 'a'), ('e', 's'), ('l', 'd'), ('l', 'f'), ('o', 'f')]
!!!(19)Max和Min的高级使用
字典中比较值的大小
a_dic = {'chris':19,'joe':20,'allen':22} print(max(a_dic.values()))
此时输出值为22
有以下需求,在一个字典中,去除最大值及其对应的名字
!!先将其拉链化,组成一个新的数据类型再比较,如下
a_dic = {'chris':19,'joe':20,'allen':22} print(max(zip(a_dic.values(),a_dic.keys())))
此时输出值为(22, 'allen')
终极玩法
取列表中字典里值最大的一组数据
a = [ {'name':'chris','age':22}, {'name':'joe','age':20}, {'name':'allen','age':19}, ] print(max(a,key = lambda dic: dic['age']))
此时输出值为{'name': 'chris', 'age': 22}
(20)ord() 取出字符在ascill码里对应的数字
(21)pow() 为几的几次方 如pow(2,3) 为8 第三个参数则是取余 % 如pow(2,3,2) 等同于 2**3 %2
(22)round() 四舍五入 round(3.5) 为4
(23)set() 变成集合的形式
(24)slice() 切片 可以设置步长
a = slice(0,3) b = 'chris' print(b[a])
(25)sorted() 内部for循环后排序 不同类型不能排序 如数字和字符串
a = [ {'name':'chris','age':22}, {'name':'joe','age':20}, {'name':'allen','age':19}, ] print(sorted(a,key = lambda dic: dic['age']))
此时输出值为[{'name': 'allen', 'age': 19}, {'name': 'joe', 'age': 20}, {'name': 'chris', 'age': 22}]
字典中按值排序
a = { 'chris':900, 'joe':10, 'allen':777 } print(sorted(a,key=lambda x:a[x]))
此时输出值为['joe', 'allen', 'chris'],若要带上values,可以用zip进行拉链
(26)vars()没有设置参数 则和 locals()一样 设置参数 则显出他的所有功能,并以字典的形式显示
(27)import 调用模块 调用其他文件下的功能 不要加后缀名py
如:import test 如何调用
test.+函数 如 test.aaa()
如果文件名为字符串类型 如 'test' 此时使用_import_()
如:
a=_import_('test')
a.aaa()
此时便可以执行
(28)open() 打开文件
11.文件操作
三步:
1.打开文件,得到文件句柄并赋值给一个变量
2.通过句柄对文件进行操作
3.关闭文件
a=open('蔡晓武','r',encoding='utf8') r表示只可读 b=a.read() #read完后光标位置就到末尾了 print(b)
a.close()
注意编码格式,encoding可以设置 !!!注意用完后要关闭文件,释放内存!!!
读模式下:'r'
1.readable() 测试是否可读
2.readline()一次读一行
3.readlines() 读取所有行,并放到一个列表内
写模式下:'w' 如果文件不存在,就创建一个新的
a=open('蔡晓武','w',encoding='utf8') a.write('aad\n') a.write('chris\n')
1.write()
2.writelines(['adsf\n','gasg\n']) 这里写的内容必须是列表
#写的内容必须是字符串!!!!不能是数字
追加操作模式:'a' 模式
a=open('蔡晓武','a',encoding='utf8') a.write('写到最后\n') a.write('最后\n')
追加到最后一行
读写模式:'r+'
With操作 可以不用close!
with open('蔡晓武','a') as a: a.write('写到最后\n') a.write('最后\n')
当写的代码太长时,找个合适的位置加入\ 再enter
字节读取模式:'rb' #b的模式不能指定编码
'字符串'-------encode--------> bytes
bytes--------decode--------->'字符串'
当要读取出字节模式下的数据时,解码要用一样的编码格式
f = open('蔡晓武','rb') a = f.read() print(a.decode('utf-8'))
此时就可以读取出来了,否则将以二进制的方式显示
将字符串转换为字节模式 bytes()一定要指定字符编码格式!!!
f = open('蔡晓武','wb') f.write(bytes('hello',encoding='utf-8'))
或者 f.write('蔡晓武'.encode('utf-8'))