2,使代码可读性更好。自定义函数:def关键字空格函数名:英文冒号函数体执行函数函数名+()函数是以功能为导向的。函数的返回值:return作用:1)函数中遇到return结束函数,下面代码不执行,相当于while循环中的break。2)将函数里面的值返回给函数的执行者(调用者)。
1)举例deflogin():print(111)print(222)returnprint(333)login()#函数执行者2)举例:函数的初识:deflogin():print(111)print(222)return666print(login())#666return使用方法总结:
第一种情况:只有return什么都没写,或者函数中没有return,函数执行者返回None什么是None:python为了节省内存,对于[],{},(),'',set()只要是空的都保存在None中,是个独立的数据类型。第二种情况:returnNone(将None写出来)第三种情况:return单个值(这个值是什么类型,返回的值给执行者就是什么类型)
deflogin():a=2b=3returnaprint(login())#2第四种情况:return多个值(以元组的形式返回给函数的调用者)
函数的使用:
常用方法计算元素长度:l1=[1,2,3,4,1,6,9,10]print(len(l1))自定义函数计算方法:defmy_len():l1=[1,2,3,4,1,6,9,10]count=0foriinl1:count+=1returncountprint(my_len())*************************************************函数的参数:举例说明:defmy_len(a):#形式参数形参l1=acount=0foriinl1:count+=1returncountl1=[1,2,3,4,1,6,9,10]my_len(l1)#实际参数实参
实参角度:三种位置参数:实参和形参数一一对应举例说明:deftes(a,b,c):print(111)print(a,b,c)tes(22,'alex',[11,22,33])关键字参数:也得一一对应实参和形参数量相等,实参的顺序可以变(可以理解为分别赋值)举例说明:deffunc(x,y):print(x,y)func(y=333,x=444)#也可以不用写x=y=直接写值也行混合参数(位置参数,关键字参数):整体数量要一一对应,位置参数必须在前面多个关键字参数位置可以互换,不用一一对应举例说明:deffunc(x,y,z):print(x,y,z)
func(111,222,z=555)
形参角度:三种位置参数:相对于实参位置而言也得一一对应
默认参数:默认参数必须放在形参的位置参数后面,不传值就是默认值,传值则覆盖默认值。举例说明:deffunc2(x,y,z=100):#默认参数print(x,y,z)func2(1,2)
deffunc2(x,y,z=100):print(x,y,z)func2(1,2,3000)#为z赋值
动态参数:用户传入到函数中的实参数量不定时,或为以后拓展,此时要用到动态参数。此时要用到动态参数*args,**kwargs(这个英文可以改,他们只是个变量,也叫万能参数)*args接受的是所有的位置参数。形成元组**kwargs接受的是所有的关键字参数。形成字典举例说明:deffunc1(*args,**kwargs):print(args)print(kwargs)func1(1,2,3,4)func1(x=4,y=5,z=6)func1(1,2,3,x=4,y=5,z=6)动态参数的位置:*args:位置参数*args默认参数**kwargs:放在最后面:位置参数*args默认参数,**kwargs.举例说明:
deffunc1(a,b,*args,sex='男',**kwargs):print(a)print(b)print(args)print(sex)print(kwargs)func1(1,2,5,6,7,8,9,sex='女',x=6,y=5,name='alex')补充:#如果函数的默认参数是可变的数据类型,无论使用多少次默认参数,都是一个,并且如果默认参数是{}[]()等实参位置不用加索引(这里和学习深浅copy有相似地方)defextendlist(val,list=[]):list.append(val)returnlistlist1=extendlist(10)list2=extendlist(123,[])list3=extendlist('a')list=[10,'a']#默认列表list=[123,]#新列表list=[10,'a']#一变都变,默认列表
print('list1=&s'%list1)
*的魔性用法:将可迭代对象直接将每个元素加入到args中
在函数的定义的时候,*代表聚合和聚合举例说明:
deffunc3(*args,**kwargs):#函数的定义,*用意是聚合print(args)l1=[1,2,3]l2=[11,21,32]func3(*l1,*l2)#*的用意是打散deffunc3(*args,**kwargs):print(args)print(kwargs)dic1={'name':'alex'}dic2={'age':1000}func3(**dic1,**dic2)#是两个*补充:
deffunc(*args,**kwargs):在这是聚合print(args)#(1,2,3)print(*args)#123在这又打散func1(*[1,2,3],**{'name':'alex'})在这*是打散
deffunc(*args,**kwargs):print(*kwargs)#(1,2,3)#print函数无法接受**kwargs关键字参数->print('name'='alex')print(kwargs)#但是你加*会输出字典的键。func(*[1,2,3],**{'name':'alex','ags':18})
*处理剩下的元素*除了在函数中可以这样打散,聚合外,函数外还可以灵活的运用:
#之前讲过的分别赋值a,b=(1,2)print(a,b)#12#其实还可以这么用:a,*b=(1,2,3,4,)print(a,b)#1[2,3,4]名称空间,加载顺序等
当程序运行时,代码从上至下以此读取,遇到变量与值,它会在内存中开辟一个空间,存放变量与值得内存地址的对应关系。这样存储变量与值得对应关系的空间叫做名称空间(命名空间)又称全局名称空间
当解释器遇到函数时,它会将函数名存储在内存中,但是对于函数体漠不关心。当函数执行时,它会通过函数名找到函数体,然后将函数体里面的变量等对应关系存放在一个临时开辟的空间中,随着函数的结束,临时的空间关闭,这样的空间叫做临时名称空间。另一点:函数中的变量只能在函数内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。
内置名称空间:存放了python解释器为我们提供的名字:input,print等如len()print()input()
名称空间:内置名称空间全局名称空间局部名称空间
加载顺序:内置名称空间-->全局名称空间(程序运行时)-->临时(局部)名称空间(函数调用时执)
作用域:全局作用域:内置名称空间,全局名称空间局部作用域:局部名称空间
取值顺序(只能单项):临时(局部)名称空间-->全局名称空间-->内置名称空间llocalEecloseGglobalBbuilt-in举例说明:
sum=666#globaldeffunc1():sum=555#ecloseprint(sum)definner():sum=111#localprint(sum)inner()func1()检测那些变量是全局的那些事局部的,globals()locals()#locals():函数会以字典的类型返回当前位置的全部局部变量(可以检查局部,也可以检查全局)。#globals():函数以字典的类型返回全部全局变量。
defextendList(val,list=[]):list.append(val)print(locals())returnlist#这个list是局部的ret=extendList(1)#但是list返回的值是全局的print(globals())函数的嵌套:主要是要明白数据的执行顺序。
举例说明:deffunc1():a=666print(666)deffunc2():name='adf'print(name)func1()print(333)func2()print(555)**********************globalnonlocal关键字*******************
在全局名称空间里得到局部名称空间的变量用:1,return举例说明:
deffunc1():globalnamename='alex'func1()print(name)2)在局部作用域中更改一个全局变量(在局部作用域想要对全局作用域的全局变量进行修改时,需要用到global(限于字符串,数字))
name='小旋风'deffunc1():globalnamename='男神'func1()print(name)补充:局部作用域对全局作用域的变量(此变量只能是不可变的数据类型)只能进行引用,而不能进行改变,对于可变的数据类型,函数中如果对其进行操作,改变全局变量不用引入global
l1=[1,2,3]deffunc1():l1.append(666)func1()print(l1)**nonlocal如果上一层没有变量就会报错(在局部作用域如果想对父级作用域的变量进行改变时,需要用到nonlocal)
1,不能改变一个全局变量,但是可以改变局部变量在局部作用域汇中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改并且引用的哪层,从那层及以下此变量全部发生改变(先是引用,后是修改),这里的哪层指的是同层及同层以下嵌套的。举例说明:
deffunc1():name='男神'print(name)definner():nonlocalnamename='小旋风'print(name)inner()print(name)func1()defadd_b():b=42defdo_global():b=10print(b)#10defdd_nonlocal():#nonlocalb#10b=b+20#30print(b)#30dd_nonlocal()print(b)#30do_global()print(b)#42add_b()补充:
count=1deffunc4():count=count+1#这样会报错print(count)func4()#局部只能引用全局的变量,不能修改,如果想修改,加global。count=1deffunc4():globalcountcount=count+1#这样就不会报错print(count)func4()#子函数只能引用父函数的变量,不能修改,如果想修改,加nonlocal。deffunc4():count=3definner():nonlocalcount#加个nonlocal之后就不会再报错,否则会报错。count=count+1print(count)inner()func4()*************************函数名的应用***********************
什么是函数名:1,他是一个变量直接打印函数名得到的是函数的内存地址,加个()就执行。函数名其实可以认为是特殊的变量,学名:第一类对象。2,函数名能进行赋值运算。
deffunc1():print(666)f1=func1f1()3,函数名可以作为函数的参数
deffunc1():print(666)deffunc2(x):x()print(555)func2(func1)4,函数名可以作为容器数据类型的元素。
deffunc1():print(666)deffunc2():print(222)deffunc3():print(111)deffunc4():print(777)l1=[func1,func2,func3,func4]foriinl1:i()#一一全部执行5,函数名可以作为函数的返回值
deffunc1():print(666)deffunc2(x):print(222)returnxret=func2(func1)*****************************闭包*************************
补充理解(之前都没有理解闭包是干什么的):
由于闭包这个概念比较难以理解,尤其是初学者来说,相对难以掌握,所以我们通过示例去理解学习闭包。
给大家提个需求,然后用函数去实现:完成一个计算不断增加的系列值的平均值的需求。
例如:整个历史中的某个商品的平均收盘价。什么叫平局收盘价呢?就是从这个商品一出现开始,每天记录当天价格,然后计算他的平均值:平均值要考虑直至目前为止所有的价格。
比如大众推出了一款新车:小白轿车。
第一天价格为:100000元,平均收盘价:100000元
第二天价格为:110000元,平均收盘价:(100000+110000)/2元
第三天价格为:120000元,平均收盘价:(100000+110000+120000)/3元
........
series=[]defmake_averager(new_value):series.append(new_value)total=sum(series)returntotal/len(series)print(make_averager(100000))print(make_averager(110000))print(make_averager(120000))从上面的例子可以看出,基本上完成了我们的要求,但是这个代码相对来说是不安全的,因为你的这个series列表是一个全局变量,只要是全局作用域的任何地方,都可能对这个列表进行改变。
series=[]defmake_averager(new_value):series.append(new_value)total=sum(series)returntotal/len(series)print(make_averager(100000))print(make_averager(110000))series.append(666)#如果对数据进行相应改变,那么你的平均收盘价就会出现很大的问题。print(make_averager(120000))那么怎么办呢?有人说,你把他放在函数中不就行了,这样不就是局部变量了么?数据不就相对安全了么?
defmake_averager(new_value):series=[]series.append(new_value)total=sum(series)returntotal/len(series)print(make_averager(100000))#100000.0print(make_averager(110000))#110000.0print(make_averager(120000))#120000.0这样计算的结果是不正确的,那是因为执行函数,会开启一个临时的名称空间,随着函数的结束而消失,所以你每次执行函数的时候,都是重新创建这个列表,那么这怎么做呢?这种情况下,就需要用到我们讲的闭包了,我们用闭包的思想改一下这个代码。
defmake_averager():series=[]defaverager(new_value):series.append(new_value)total=sum(series)returntotal/len(series)returnaverageravg=make_averager()print(avg(100000))print(avg(110000))print(avg(120000))
大家仔细看一下这个代码,我是在函数中嵌套了一个函数。那么avg这个变量接收的实际是averager函数名,也就是其对应的内存地址,我执行了三次avg也就是执行了三次averager这个函数。那么此时你们有什么问题?
肯定有学生就会问,那么我的make_averager这个函数只是执行了一次,为什么series这个列表没有消失?反而还可以被调用三次呢?这个就是最关键的地方,也是闭包的精华所在。我给大家说一下这个原理,以图为证:
上面被红色方框框起来的区域就是闭包,被蓝色圈起来的那个变量应该是make_averager()函数的局部变量,它应该是随着make_averager()函数的执行结束之后而消失。但是他没有,是因为此区域形成了闭包,series变量就变成了一个叫自由变量的东西,averager函数的作用域会延伸到包含自由变量series的绑定。也就是说,每次我调用avg对应的averager函数时,都可以引用到这个自用变量series,这个就是闭包。
内层函数对外层函数非全局变量的引用就叫闭包
判断是不是闭包,是函数名.__closure__返回的是None则不是闭包,返回cell则是。
deffunc1():name='小旋风'definner():print(name)inner()print(inner.__closure__)判断是否是闭包,如果返回cell是None否func1()另一例子:比较又迷惑性,这个也是闭包相当于在函数中name重新赋值deffunc1(x):definner():print(x)inner()print(inner.__closure__)name='小旋风'func1(name)如果此函数拥有自由变量,那么就可以侧面证明其是否是闭包函数了defmake_averager():series=[]defaverager(new_value):series.append(new_value)total=sum(series)returntotal/len(series)returnaverageravg=make_averager()#函数名.__code__.co_freevars查看函数的自由变量print(avg.__code__.co_freevars)#('series',)当然还有一些参数,仅供了解:#函数名.__code__.co_freevars查看函数的自由变量print(avg.__code__.co_freevars)#('series',)#函数名.__code__.co_varnames查看函数的局部变量print(avg.__code__.co_varnames)#('new_value','total')#函数名.__closure__获取具体的自由变量对象,也就是cell对象。#(
闭包有什么用?
当执行一个函数时,如果解释器判断此函数闭包存在,这样函数就有一个机制,闭包的所在的临时名称空间不会随着函数的执行完毕而消失。
闭包的作用:保存局部信息不被销毁,保证数据的安全性。
闭包的应用:
可以保存一些非全局变量但是不易被销毁、改变的数据。
装饰器。
比较有意思的一道题:
deffunc():deffunc1():name='小旋风'deffunc2():nonlocalnamename='男神'deffunc3():globalnamename='女神'name='小屁孩'func1()print(name)func2()print(name)func3()print(name)func()print(name)******************************装饰器********************************
装饰器定义及作用:装饰器本质还是一个函数,它是用来对函数函数进行装饰的函数,在不改变原来函数调用的基础上给原来的函数添加新的功能
装饰器的原则:开放封闭原则
defwrapper(f):definner(*args,**kwargs):''执行被装饰函数之前的操作''''ret=f(*args,**kwargs)''执行被装饰函数之前的操作''''returnretreturninner@wrapperf()*******************函数的有用信息**************************
#通过立flag=TrueFalse来决定控制函数是否需要被装饰importtimeflag=Truedeftimmer(f):definner(*args,**kwargs):ifflag:start_time=time.time()time.sleep(0.3)ret=f(*args,**kwargs)end_time=time.time()print('执行效率%s'%(end_time-start_time))returnretelse:ret=f(*args,**kwargs)returnretreturninner@timmerdeffunc1():print(111)@timmerdeffunc2():print(222)@timmerdeffunc3():print(333)func1()func2()func3()这个就是带参数的装饰器,其作用就是能够很好的控制被装饰器的使用功能,就是在装饰器的原来基础上在加个函数。
defwrapper1(func):#func=f:f是函数名definner1():print('wrapper1,beforefunc')#2func()print('wrapper1,afterfunc')#4returninner1defwrapper2(func):#func=inner1definner2():print('wrapper2,beforefunc')#1func()#执行inner1()print('wrapper2,afterfunc')#5returninner2@wrapper2#f=wrapper2(f)里面的f新变量=inner1外面的函数是最新变量=inner2@wrapper1#f=wrapper1(f)里面的f函数名,外面的f新变量=inner这个执行结束之后后,开始执行第二个装饰器(两个装饰器,先执行距离最近的装饰器在执行其他的也就是由进到远)deff():print('inf')#3f()#inner2()'''执行结果wrapper2,beforefuncwrapper1,beforefuncinfwrapper1,afterfuncwrapper2,afterfunc'''
补充知识点:
装饰器的本质是闭包开放封闭原则(写代码最好不要写死):允许代码扩展,添加新功能,如果函数交给其他人使用,所以进行封闭
可迭代对象定义:内部含有__iter__方法的就是可迭代对象,遵循可迭代协议。用dir函数可以检测:可以通过dir()去判断一个对象具有什么方法,dir()会返回一个列表,这个列表中含有该对象的以字符串的形式所有方法名print(dir('123'))#返回的是列表print('__iter__'indir([1,2,3]))用这个方法判断列表中是否存在__iter__
dir():查看对象的所有方法
可迭代对象的优点:
可以直观的查看里面的数据。
可迭代对象的缺点:
1.占用内存。
2.可迭代对象不能迭代取值(除去索引,key以外)。
那么这个缺点有人就提出质疑了,即使抛去索引,key以外,这些我可以通过for循环进行取值呀!对,他们都可以通过for循环进行取值,其实for循环在底层做了一个小小的转化,就是先将可迭代对象转化成迭代器,然后在进行取值的。那么接下来,我们就看看迭代器是个什么鬼。
迭代器:可迭代对象通过.__iter__()可以转化成迭代器,遵循迭代器协议,其实它也是数据类型。在python中,内部含有'__Iter__'方法并且含有'__next__'方法的对象就是迭代器。迭代器也是一种数据类型:1)内存占用非常小,节省内存;2)满足惰性机制,在循环到第四次时,再次循环它会从第5次继续执行;迭代器是未来做数据类型;3)取值过程单项不可逆的首选方式
l=[1,2,3]l_obj=l.__iter__()#生成迭代器l_obj=iter(l)print(l_obj)print(l_obj.__next__())迭代器取值方法:
1).__next__():使用一次就取一次值,值取完后会报错。2)for循环:for循环其实就是将可迭代对象,转化成迭代器,通过.__next__()来实现元素读取。需要注意一点:
l=[1,2,3]l_obj=l.__iter__()print(l_obj.__next__())#在这里执行.__next__()后再执行for循环执行的是剩余的内容,符合迭代器的惰性机制。print()foriinl_obj:print(i)#只能打印出23生成迭代器以及取值的另一种方法:
l1=[1,2,3,4,5,6]obj=iter(l1)print(next(obj))print(next(obj))print(next(obj))怎样判断是否是迭代器:
1)内部还有.__iter__()和.__next__()方法的就是迭代器。2)fromcollectionsimportiterablefromcollectionsimportiteratorprint(isinstance('123',iterable))#判断是否是可迭代对象isinstance可以判断所有属性,可以判断任意数据类型。print(isinstance('123',iterator))#判断是否是迭代器
实际上可迭代对象是不可以一个一个的一次取值的,因为他没有__next__方法,但是for循环提供一个机制:1)将可迭代对象转化成迭代器2)利用__next__进行取值。3)用try异常处理方法防治报错。如下例子:模拟for循环机制
l=[1,2,3,4,5]l_obj=l.__iter__()whileTrue:try:print(l_obj.__next__())exceptStopIteration:break迭代器:是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。
应用:当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。(可参考为什么python把文件句柄设置成迭代器)
*************************生成器******************************
生成器的本质也是迭代器,迭代器都是Python给你提供的已经写好的工具或者通过数据转化得来的,(比如文件句柄,iter([1,2,3])。生成器是需要我们自己用python代码构建的工具。最大的区别也就如此了。
两种构建方法:
1,通过生成器函数构建。2,通过生成器推导式构建。
1)函数构建生成器:将函数中的return换成yield,这样func就不是函数了,而是一个生成器函数
deffunc1():#函数体就是生成器函数print(666)yield222#yield的值是可以返回给生成器的yield777g_obj=func1()#生成器对象在下面通过func1().__next__()执行这个函数print(g_obj.__next__())#生成器也是.__next__()取值一个yield对应一个.__next__(),next数超过yield的数就会报错。print(g_obj.__next__())生成器作用的说明举例:defcloth2():foriinrange(1,10001):yield'衣服%s'%i#注意这里的yield不像Reture位置那么死板,比较灵活g=cloth2()foriinrange(1,51):print(g.__next__())foriinrange(1,151):print(g.__next__())#或者print(next(g))send的用法
1)send具有next功能,一次只能执行一个yield2)send可以给上一个yield传值传什么值都行3)第一个取值不能使用send但可以是send(None)
deffunc1():count=yield#可以通过这个方式打印出yield被更改的值print(count)yield777yield888g_obj=func1()print(g_obj.__next__())print(g_obj.send(2))defgen(name):print(f'{name}readytoeat')while1:food=yield222print(f'{name}starttoeat{food}')dog=gen('arry')next(dog)#第一次必须用next让指针停留在第一个yield后面,这个next其实是执行到yield222但是yield是返回值要看到这个返回值需要print(next(dog))#与next一样,可以获取到yield的值ret=dog.send('骨头')print(ret)yieldfrom的用法
#对比yield与yieldfromdeffunc():lst=['A','B','C','D']yieldlstg=func()print(g)print(next(g))#只是返回一个列表deffunc():lst=['A','B','C','D']yieldfromlstg=func()print(g)#他会将这个可迭代对象(列表)的每个元素当成迭代器的每个结果进行返回。print(next(g))print(next(g))print(next(g))print(next(g))'''yieldfrom['A','B','C','D']等同于:yield'A'yield'B'yield'C'yield'D''''需要注意yieldfrom是将列表中的每一个元素返回,所以如果写两个yieldfrom并不会产生交替的效果
deffunc():lst1=['A','B,'C','D']lst2=['E','F','G','k']yieldfromlst1yieldfromlst2g=func()foriing:print(i)2)推导器构建
列表推导式:能用列表推导式完成的,用python代码都可以完成什么是列表推导式:就是用一句话构建一个你想要的列表优点,简单,缺点,不能用debug
列表推导式:[变量(加工后的变量)for变量in可迭代对象]-----遍历模式li=[iforiinrange(1,12)]print(li)
[变量(加工后的变量)for变量in可迭代对象if判断]-----筛选模式li=[iforiinrange(101)ifi%2==0]print(li)生成器表达式:g=(i*iforiinrange(1,11))只是将[]改为()就能成为生成器对象print(g)
列表推导式简单明了但是占内存还有字典集合推导式(需求不多,先不学)。生成器表达式节省内存但是不易看出
#求出下面列表中的两个小列表中含有两个‘e’的元素names=[['tom','billy','jefferson','andrew','wesley','steven','joe'],['alice','jill','ana','wendy','jennifer','sherry','eva']]fornameinnames:foriinname:ifi.count('e')==2:print(i)#使用列表推导式,一般for循环最多循环两层li=[ifornameinnamesforiinnameifi.count('e')==2]print(li)字典推导式:这里只是简单介绍一个
#将下面的字典键与值互换位置mcase={'a':10,'b':34}mcase_frequency={mcase[k]:kforkinmcase}print(mcase_frequency)*****************************内置函数******************************
目前python里共有68个内置函数
黄色一带而过:all()any()bytes()callable()chr()complex()divmod()eval()exec()format()frozenset()globals()hash()help()id()input()int()iter()locals()next()oct()ord()pow()repr()round()
红色重点讲解:abs()enumerate()filter()map()max()min()open()range()print()len()list()dict()str()float()reversed()set()sorted()sum()tuple()type()zip()dir()
蓝色未来会讲:classmethod()delattr()getattr()hasattr()issubclass()isinstance()object()property()setattr()staticmethod()super()
range()自定制一个数字范围列表frozenset()冻结:语法:frozenset([iterable]),返回一个冻结的集合,冻结后集合不能再添加或删除任何元素。
locals()以字典形式返回当前位置全部局部变量
defextendList(val,list=[]):list.append(val)print(locals())#打印的是{'val':1,'list':[1]}returnlistret=extendList(1)print(globals())#{'extendList':
eval:去除字符串的引号,返回对应内部的值。s='{"a":1,"b":3}'dic=eval(s)print(dic,type(dic))exec:去除字符串的引号,没有返回值,但是能执行里面的结果
ret='''name=input('请输入名字:').strip()ifname=='xiaoxuanfeng':print(666)'''exec(ret)print函数:
print(1,2,3,sep='*')#改变设定打印元素的连接方式print('我是',end="")#end控制换行print('xiaoxuanfeng')
f1=open('log',encoding='utf-8',mode='w')print('666',file=f1)#操作文件句柄,写入文件。f1.close()
help:函数用于查看函数或模块用途的详细说明。
complex(复数):
bin:将十进制转换成二进制并返回。oct:将十进制转换成八进制字符串并返回。hex:将十进制转换成十六进制字符串并返回。
数学运算:abs:函数返回数字的绝对值。divmod:计算除数与被除数的结果,返回一个包含商和余数的元组print(divmod(7,3))round:保留浮点数的小数位,默认保留整数。
pow:求x**y次幂(三个参数为x**y的结果对z取余)
print(pow(2,3))#两个参数为2**3次幂print(pow(2,3,3))#三个参数为2**3次幂,对3取余。sum:对可迭代对象进行求和计算(可设置初始值)print(sum([1,2,3,4]))print(sum([1,2,3,4],100))min:返回可迭代对象的最小值(可加key,key为函数名,通过函数的规则,返回最小值)print(min([1,3,5,7,-4]))print(min([1,3,5,7,-4],key=abs))max:返回可迭代对象的最小值(可加key,key为函数名,通过函数的规则,返回最大值)
list:将可迭代对象创建列表tu=(1,2,3)print(list(tu))这个其实是创建也可理解为转换
l1=list((1,2,3))print(l1)
和函数组合使用#定义一个列表,然后根据一元素的长度排序lst=['天龙八部','西游记','红楼梦','三国演义']#计算字符串的长度deffunc(s):returnlen(s)print(sorted(lst,key=func))#结果:#['西游记','红楼梦','天龙八部','三国演义']和lambda组合使用lst=['天龙八部','西游记','红楼梦','三国演义']print(sorted(lst,key=lambdas:len(s)))结果:['西游记','红楼梦','天龙八部','三国演义']reversed:将一个序列翻转,并返回此翻转序列的迭代器l1=[11,22,33,44,77,66]l_obj=reversed(l1)foriinl_obj:print(i)slice:构造一个切片对象,用于列表的切片
l1=[11,22,33,44,77,66]l2=[111,222,333,444,775,666]print(l1[1::2])
rule=slice(1,len(l2),2)print(l2[rule])
以什么方式切l1就以什么方式切l2
bytes:str-->bytes
s1='asad'b1=s1.encode('utf-8')print(b1)b2=bytes(s1,encoding='utf-8')print(b2)
#通过构造函数创建空bytesb1=bytes()#通过空字符串创建空bytesb2=b''
bytearrayret=bytearray('abc',encoding='utf-8')#类比:[97,133,......]print(id(ret))print(ret)#bytearray(b'abc')print(ret[0])#得到'a'在accii的位置。ret[0]=65print(ret)
memoryview:#分字节去转化成strb1=bytes('您好',encoding='utf-8')print(b1)ret=memoryview(bytes('您好',encoding='utf-8'))print(len(ret))print(ret)print(bytes(ret[:3]).decode('utf-8'))print(bytes(ret[3:]).decode('utf-8'))
ord:输入字节找该字节编码的位置。print(ord('a'))print(ord('中'))#unicode编码chr:输入位置数字找出其对应的字符print(chr(65))print(chr(20013))ascii:是ascii码中的返回值,不是就返回/uprint(ascii('a'))print(ascii(1))print(ascii('中'))
repr:返回一个对象的string形式(原形毕露)
msg='名字%r'%('xiaoxuanfeng')print(msg)#传的是字符串那么返回的就是字符串
print('{"name":"abc"}')print(repr('{"name":"abc"}'))
print(sorted([1,2,3,4,5,-6]))print(sorted([1,2,3,4,5,-6],key=abs))可以加参数
l=[('a',1),('c',2),('d',4),('b',3),]print(sorted(l))
deffunc1(x):returnx[1]l=[('a',1),('c',2),('d',4),('b',3),]print(sorted(l,key=func1))
students=[('john','A',15),('jane','B',12),('dave','B',10)]#按照年龄进行排序print(sorted(students,key=lambdax:x[2])
all:可迭代对象中,全都是True才是True
all()函数用于判断给定的可迭代参数iterable中的所有元素是否都为TRUE,如果是返回True,否则返回False。
元素除了是0、空、None、False外都算True(这里的空指的是可迭代对象里面的元素如果是空列表,元组,返回的True)。bool值不是可迭代对象
>>>all(['a','b','c','d'])#列表list,元素都不为空或0True>>>all(['a','b','','d'])#列表list,存在一个为空的元素False>>>all([0,1,2,3])#列表list,存在一个为0的元素False>>>all(('a','b','c','d'))#元组tuple,元素都不为空或0True>>>all(('a','b','','d'))#元组tuple,存在一个为空的元素False>>>all((0,1,2,3))#元组tuple,存在一个为0的元素False>>>all([])#空列表True>>>all(())#空元组True
any:可迭代对象中,有一个True就是True
zip:拉链方法,返回的是一个迭代器。
函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,
然后返回由这些元祖组成的内容,如果各个迭代器的元素个数不一致,则按照长度最短的返回
l1=[1,2,3,4]tu1=('小旋风','男神','女神')set={'*','**','***','****'}
obj=zip(l1,tu1,set)#返回的是元组。(1,‘小旋风’,‘**’)...foriinobj:print(i)
map:循环模式将第二个可迭代对象的元素作为第一个函数的参数进行循环执行map(function,iterable)
deffunc2(x):returnx**2obj=map(func2,[1,2,3,4])foriinobj:print(i)
deffunc2(x,y):returnx+yobj1=map(func2,[1,2,3,4],(2,3,4,5))foriinobj1:print(i)filter:筛选模式,filter(function,iterable)根据前面function的条件,对后面iterable可迭代对象进行筛选。
deffunc(x):returnx%2==0ret=filter(func,[1,2,3,4,5,6,7])print(ret)foriinret:print(i)
结合lambda函数可以更简写为ret=filter(lambdax:x%2==0,[1,2,3,4,5,6,7])
lambda匿名函数,一句话函数和mapfilter函数相结合。deffunc(x):returnx%2==0deffunc1(x,y):returnx+yret=lambdax,y:x+y#lambda就相当于defret相当于函数名ret(2,3)#执行相当于func(x)print(ret(2,3))
deffunc1(x,y):returnxifx>felseyret=lambdax,y:xifx>yelsey#三符运算print(ret(2,3))
ret1=lambdax:x%2==0ret=filter(ret1,[1,2,3,4,5,6,7])
foriinret:print(i)
#内置函数:mapfiltersortedmaxmin#匿名函数:lambda#递归函数:***********************递归函数*********************什么是递归函数:自己调用自己deffunc1():print(666)func1()func1()#自己调用自己,每次执行一次func1()会重新再开辟个空间
#默认最大递归深度998count=0deffunc1(n):n+=1print(n)func1(n)func1(count)
#引用sys模块设置最大递归深度importsyssys.setrecursionlimit(1000)
count=0deffunc1(n):n+=1print(n)func1(n)func1(count)#求年龄defage(n):ifn==1:return23else:returnage(n-1)+2
print(age(4))**********************************二分查找是最简单的算法********************1,数字序列,有序,不重复。
****************************************题************************************
延续上面的更改如下:
whileTrue:print('''1,访问淘宝2,访问淘宝超市3,访问京东4,访问京东超市''')choice=input('请输入你的选项':).strip()ifchoice.isdigit():choice=int(choice)if0