python全栈 S3--16day--(2)包括17day的内容
一、函数作用域
定义:函数作用域和定义时的调用有关系,和在哪个位置进行调用没有关系
def test(): name="jay" def foo(): name="james" def bar(): print (name) return bar return foo # foo=test() # bar=foo() # bar() # 上面三个步骤,代表着作用域与定义时有关系,与在哪个位置调用没有关系 # test()()() # 上面这个是上面那三个的简化可以这样表示
作用域的补充
1、函数必须一级一级的执行,从外到里面。不能直接执行里面的
2、return打印的就是一个内存地址。如果没有return就默认打印none
二、匿名函数(lambda)
# 使用lambda的函数表达方式 # lambda x:x+1 x代表形参,x+1代表的是return的值,也就是返回值,与下面的def中的一一对应,如果想要调用必须先付给一个变量 jay=lambda x:x+1 print (jay(10)) # 使用def关键字的函数表达方式 def test(x): return x+1 test(10) print (test(10))
1、匿名函数通常情况下的表达方式就是:lambda x:x+1,但是通常情况下。匿名函数与其他函数一起来使用
2、如果这样来定义匿名函数的话,他是不占用内存的lambda x:x+1
3、想要被调用的话,就要给它付一个变量即:
jay=lambda x:x+1
jay()表示调用这个函数,如果想要打印出结果,还要给他定义一个变量james=jay()
print(james)这个时候才会打印出结果
4、匿名函数的形参可以是多个值,定义后面的返回值不能是复杂逻辑,可以是简单的加减运算,但是传入的必须是一个元组的形式
lambda x,y,z:if x=2,y=3 这种是错误的
lambda x,y,z:x+1,y+1,z+1 这种是错误的
lambda x,y,z:(x+1,y+1,z+1) 这种是正确的
三、函数式编程
编程方法论:
面向过程:就是
函数式、
面向对象
纯函数编程式语言:Hashell、clean、erlang
函数式编程语言:就是将数学方面上的的函数,与python中的函数混合一起使用
y=2*x+1 def test(x): return 2*x+1
面向对象:表示将函数中的代码更细节化
y=2*x+1 def test(): res=2*x res=res+1 print (res)
总结:函数式编程对比面向对象可读性较差,但是开发效率高
1、高阶函数
函数式编程要求:不定义变量,不修改变量
# 把函数当作一个参数传递给另一个函数 def test(n): print (n) def foo(): print ("james") a=test(foo) print (a) b=test(foo()) print (b)
# # 返回值包括另一个函数 # def test(): # print ("Jay") # def foo(): # return test 这里也可以写return test()表示直接去调用另一份函数 # a=foo() # a() # print(a)
#######以上两点就叫函数式编程中的高阶函数
2、递归函数。执行完一级以后有的会保存,有的不会保存
# 这个时候执行完最外面这层函数,是不保存的,因为这个函数代码块已经全部执行完成 def foo(): print ("jay") return test foo() # 这个时候执行完最外面这层函数,是保存的,因为这个函数代码块还没有全部执行完成 def foo(): print ("jay") return test print ("james") foo()
3、函数式编程尾递归调用优化
定义:在函数的最后一步调用另一个函数(最后一步不一定是最后一行)
def foo(n): if n<5: return n elif n==10: return ("james")函数在这步结束了,这就是最后一步 else: return "jay"而这里是函数的最后一行 v=foo(10) print(v)
4、map函数
map函数的使用方法
# map(lambda x:x+1,li) # map函数的使用方法:括号里面第一个是传入的处理逻辑,后面那个位置必须传入的是一个可迭代对象 # 处理逻辑就是你想给后面这个可迭代对象,进化成一个什么样子的函数, # 这个返回的值是一个可迭代对象地址,必须要转化成一个list对象,且print出来最后出结果 # list(map(lambda x:x+1,li)) # print(list(map(lambda x:x+1,li)))
如果不使用map函数,想要执行一样的操作,会执行以下代码
li=[1,2,3,4,5] def add_one(x): return x+1 def map_foo(a,b): ret=[] for i in li: v=a(i) ret.append(v) return ret s=map_foo(add_one,li) print(s)
def add_one(x):
return x+1
上面这个函数可以使用匿名函数,转化成如下形式
lambda x:x+1
4、filter函数的使用
补充知识点:如果想要保存打印的数据,必须将打印出来的结果进行赋值
如果不使用filter函数,想要将下面列表中的“sb”人名全部去掉
li=["sb_james","sb_aimee","sb_smile","jay"] def test(arry): res=[] for i in arry: if not i.startswith("sb"): res.append(i) return res res=test(li) print (res)
如果想要使用filter函数,记住一点,可迭代对象进行for循环之后赋值给前面的函数,但是前面的函数是根据布尔值来取值,ture会保存值,false则会舍弃值,所以请注意下面代码中的not的使用才会获取到,列表中没有“sb”的字符串
li=["sb_james","sb_aimee","sb_smile","jay"] def test(n): return n.startwith("sb") v=filter(lambda n:not n.startswith("sb"),li) print (list(v))
5、reduce函数的使用
from functools import reduce##这个是先在functools这个块中调用reduce这个函数,才能使用 test=[1,2,3,4,100] res=reduce(lambda x,y:x+y,test,1) print (res)
补充:大数据中的map reduce
总结:
map是调用列表,并且依次处理,最终得到的还是这个列表,与之前列表的个数、位置是一样的
filter是调用列表,并且遍历一遍,判断每一个元素得到布尔值,如果是ture保留下来,最终得到的是个新列表
reduce是调用列表,可以将一个完整的序列,通过某个方法,压缩到一起,得到一个值(进行合并操作,还可以设定初始值)
四、内置函数的使用方法
# 1、abs 获取一个数的绝对值 # print(abs(-5)) # 2、all 代表全部,将一个序列中所有的元素依次拿出来做布尔运算 # print (all[1,2,3,4,0,""])错误格式缺少一个括号 # print (all([1,2,3,4,0,""]))最终返回的值为一个布尔值。只要要一个数为假,则结果就为假 # print(all("1230"))这个代表传入的是一个元素 # print(all(""))这个比较特殊。如果只传入一个空字符串,则返回结果为ture # 其他的根据方法自己去尝试 # 3、any的用法是只要一个为真,则结果就为真,与all是相反的 # print(any(["jay","",2,3,4,0])) # 4、bin把十进制转化成二进制 # print(bin(3)) # 5、bool 判断元素的布尔值类型,并且打印出来 # print(bool(0)) # print (bool("")) # print (bool(None)) # 除了上面这三个返回值为false,其余都返回ture # 6、bytes 编码,表示一个字符用几个二进制表示,后面必须写上你选择的编码类型,通过这个类型的编码转 # 化成二进制,且后面不能写unicode,因为Unicode在内存中是写好的 # print(bytes("你好",encoding="utf-8")) # print(bytes("你好",encoding="gbk")) #主要功能:如果想要在网络上进行传输,必须要转化二进制 # print(bytes("你好",encoding="ascll"))ascll不能进行编码 # 7、decode 解码,要求用什么编码就要用什么解码,如果不写解码格式,默认为用utf-8 # print(bytes("你好",encoding="utf-8"))编码 # print(bytes("你好",encoding="utf-8").decode("utf-8"))解码 # print(bytes("你好",encoding="gbk"))编码 # print(bytes("你好",encoding="gbk").decode("gbk"))解码 # 8、chr 会以ascll表的形式展示出来 # print(chr(78)) # 9、dir 打印某一对象下面都有哪些方法 # print(dir(list)) # 10、divmod 表示求两个数的商,返回值,把商和余数都展示出来了 # 实例:通常网页的分页制定使用此方法 # print (divmod(10 ,2)) # print (divmod(10 ,3)) # 11、eval 将字符串中的数据结构提取出来 # li="{"name":"jay","age":18}" # print (li) # (eval(li)) # 另一个功能:计算,但是必须是字符串或者可迭代对象 # li="9*8+(8-2)" # v=eval(li) # print (v) # 12、hash 可hash的数据类型即不可变数据类型,是一种算法,一种运算逻辑 # print (hash("jsdj1243fdgdfgfg44")) # 特性:1、不管你传入的值有多长,返回的值都是固定长度 2、不可能根据hash值反推出你的值是什么 3、每次传入的值一样,所得到的hash值 # 不会发生改变 实际用途:在网上下载应用时,他的hash值是固定的,如果下载完成之后hash值被人改动过,将体现出,已经中毒 # 13、help 查看帮助,查看某个内置函数的具体用法 # print (help(hash)) # 14、hex 十进制转化16进制 # print(hex(17))十进制转化16进制 # print (bin(17))十进制转化2进制 # print (oct(17))十进制转化8进制 # 15、id 打印内存地址 # print(id(15)) # 16、isinstance 查看后面的参数是否符合后面的数据类型,返回的值是一个布尔值 # print (isinstance(1,str)) # print (isinstance(1,int)) # 17、globals 打印全局变量,,还打印出一些隐藏的全局变量 # name="jay" # print (globals()) # 18、locals 打印局部变量,,还打印出一些隐藏的局部变量 # name="james" # def test(): # name="dkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk" # print (locals()) # test() # 19 max 取最大值 min 取最小值 # li=[1,2,3,4,5,6,7,5] # print (max(li)) # print (min(li))
# 20、zip函数(拉链),最终生成的是一个内存对象 # 1、元素缺一不可 # 2、传两个参数,第一和第二个参数都必须为序列类型 # 3、序列:字符串、列表、元组 # zip(("s","b","k"),(1,2,3)) # list(zip(("s","b","k"),(1,2,3))) # print (list(zip(("s","b","k"),(1,2,3)))) # print (list(zip(("s","b","k","h"),(1,2,3))))错误 # print (list(zip(("s","b","k"),(1,2,3,4))))错误 # li={"names":"jay","age":18} # print (list(zip(li.keys(),li.values()))) # print (list(zip(li.keys()))) # print (list(zip(li.values()))) # 21、max和min的高级使用方法 # max实际上在内部进行了for循环,依次取出来看看谁的值更大。如果传入的是一个列表,那么进行for循环时,默认for的是key值 # 如果第一个元素直接能够比较出来大小,那么就不会再往下进行 # 取出来年纪最大的以及对应的人 # age_li={"sge1":14,"age2":19,"age3":17,"age4":15} # a=zip(age_li.values(),age_li.keys()) # v=list(zip(age_li.values(),age_li.keys())) # print(v) # print (max(v)) ########终极玩法
# 22、chr和ord的使用方法 # print(chr(97))数字在奥克斯码表示的字母是什么 # print (ord("a"))字母在奥克斯码表表示的数字是什么 # 23、pow 代表次方 # print(pow(3,3)) 3*3*3 # print (pow(3,3,2)) 3*3*3/2 求余数 # 24、reversed代表反转,如果反转完成之后再进行print那么还是原列表的顺序 # li=[1,2,3,4,5,] # # print (reversed(li))得到的是一个地址 # print(list(reversed(li))) # 25、round 代表的是四舍五入 # print (round(3.6)) # print (set("jay")) set将一个可迭代对象转化成元组的形式 # 26、slice 可以先定义一个切片范围再去调用 # li=[1,2,3,4,54,"jay","james"] # 常用方法 # print (li[1:3]) # # 建议使用此方法 # v=slice(1,3) # v=slice(1,4,2) 还可以定义步长 # print (li[v]) # 27、soeted 排序,不同类型不能比较大小,只有同一类型之间才可以进行比较 # li=[1,2,4,5,6,3,2] # print (sorted(li)) # age_li={"sge1":14,"age2":19,"age3":17,"age4":15} # print(sorted(age_li,key=lambda key:age_li[key])) 最终取得的是key的大小 #如果想要把键值对都取出来,那么就执行下面的操作 # # age_li={"sge1":14,"age2":19,"age3":17,"age4":15} # print(sorted(zip(age_li.values(),age_li.keys()))) # 28、type查看数据类型,str将元素转化成字符串类型 # li=(1,2,34,4,5,6) # print (type(str(li))) # li="123" # if type(li) is str: # li=int(li) # print (li+1) # 29、sum 求和 # li=[1,2,3,4,5,6] # print (sum(li)) # print (sum(range(7))) # 30、vars 与 locals一样都是调用局部变量 # def test(): # li=[1,2,3,4,5,5,"jay"] # print (locals()) # print (vars()) # test() # 31、import 导入一个模块,import不能导入字符串。而_import_就是导入字符串类型的 # import lianxi # lianxi.foo()
文件处理
# open默认打开的是系统编码,系统编码是gbk,如果编码和解码方式不一样得话就会报错,想要不报错,就要指定编码格式 # 如果文件在一个路径下就指定相对路径就行,否则要指定绝对路径 # 打开文件的三个步骤,1:打开并且赋值变量 2:开始读文件内容 3:关闭文件 # v=open("哈喽",encoding="utf8") # a=v.read() # print (a) # v.close() # 对文件的权限:r\w\a # R:读文件 # readline一次只能读取一行,读不到的内容也不会报错,如果想要不换行,添加end # v=open("哈喽","r",encoding="utf8") # print (v.readline(),end="") # print (v.readline())#一次读一行,读不到的也不会报错, # readlines将文件的所有内容放在一个列表中 # print (v.readlines()) # readable代表只能读权限,返回值为布尔值 # print(v.readable()) # 2写文件 # 写文件,如果文件存在的话,先清空掉在执行操作,如果不存在的话,会新建一个文件;换行符必须自己添加 #文件内容无论读还是写只能是字符串类型 # v=open("哈喽","w",encoding="utf8") # v.write("111111111\n") # v.write("22222\n") # # # v.writable()#是否只有写权限 # v.writelines(["jjjjjjjj\n","kkkkkkkkkk\n"])#传入一个列表 # v.close() # 3、写文件,追加到内容的最后 # v=open("哈喽","a",encoding="utf8") # v.write("kkkkkslkk") # # 4、可以合并进行操作,对于文件的修改其实就是覆盖的形式 # v=open("哈喽","r+",encoding="utf8") # v.write("kkkkkslkk") # 5、with的使用方法,可以简写,不用关闭文件了 # v=open("哈喽","r",encoding="utf8") # print(v.readlines()) # v.close() # with open("哈喽","w",encoding="utf8") as f: # f.write("jjjjjjjjjjjjjjj")
上面4操作的延伸内容 # 修改文件的本质就是将新文件对旧文件进行覆盖,所以第一个表示运行老文件,第二个表示 # 对文件进行修改了,并且创建了一个新文件 v=open("哈喽","r",encoding="utf8") a=v.readlines() v.close() v=open("喽哈","w",encoding="utf8") v.write(a[0]) v.close()
浙公网安备 33010602011771号