1.写函数写数字本质相似,赋变量做参数样样都行
如果只写一个函数名,那么它代表一个变量,因为它与变量一样都指向一个内存地址,如果函数名后面加上括号,代表执行这个函数的代码
因此函数也可以赋值给一个变脸个,变量就相当于成为了一个函数
在调用一个类的一个不存在的方法时,也会报错“该没不存在这属性”
def my_func(): print('hello') return t=my_func print(t) t() #hello
filter函数可以对一个可迭代对象进行筛选,筛选后返回一个迭代器,可以通过list()转换成列表,它由两个参数组成,第一个参数是一个函数,返回True或False,第二个参数是要进行筛选的可迭代对象
#定义一个函数,用于判断数字是否为偶数,返回True或False def f(n): return n%2==0 #定义一个列表 l=[2,3,5,1,9] #使用filter函数对列表里的元素进行筛选 偶数=filter(f,l) #返回的是一个迭代器 print(偶数) #<filter object at 0x00000211491DAA40> #通过list()方法将迭代器转换成列表 偶数=list(偶数) print(偶数) #[2]
sorted()
sorted()可以对一个可迭代对象的元素进行排序,然后返回一个排序结果,
语法是【sorted(可迭代对象,key=函数,reverse=True)】
其中key参数必须只能是一个函数,可以是系统自带的也可以是自己定义的,此外只需要填写函数名,不需要括号
reverse参数设置True表示降序,False表示升序
如果可迭代对象中的元素可以直接进行比较,比如数字、字符串等,如果是数字,进行大小的比较,如果是字符串,不是进行长度的比较,而是比较字符串的第一位、第一位相同再比较第二位,以此类推’
filter()
filter()可以用于过滤可迭代对象中的元素,通过一个返回值是True或False的函数来测试可迭代对象中的所有元素,返回的是一个迭代器,该迭代器生成那些在函数中返回True的元素
filter()的语法是【filter(函数,可迭代对象)】, 其中函数参数必须是返回值是True/False的函数
如果可迭代对象中的元素,在函数参数中的返回结果为True,那么将出现在filter()函数生成的迭代器的结果中
#通过filter()函数对数字列表进行过滤,得到该列表中的所有偶数 数字=[1,2,3,10,5,6] 偶数=filter(lambda x:x%2==0,数字) print(偶数) #<filter object at 0x000001D6C145A260> print(list(偶数)) #[2, 10, 6] #仅保留列表里长度小于5的字符串 字符串=['12212121','zfc','abc'] def f(s): return len(s)<5 a=filter(f,字符串) print(list(a)) #['zfc', 'abc']
偏函数
偏函数(partial function)是函数时编程中的一个概念,在Python中,偏函数允许你固定一个函数的一部分参数,从而生成一个新的函数
使用此功能需要from functools import partial
相当于基于一个函数生成一个新函数,新函数中的某个参数已经被固定,不需要再填写
语法是【新函数=partial(旧函数,固定参数=)】
Python的functools模块提供了partial函数,可以用于创建偏函数,这样你可以创建一个新的函数,这个函数和原来函数的行为基本一致,但是一部分参数已经预设好了
好处在于,如果经常需要使用某个函数,而该函数的某个参数值时固定的,那么就可以预设参数,使调用个更加简单
from functools import partial def power(base,exponent): return base**exponent #基于power创建一个新函数,它的base参数被预设为2 square=partial(power,exponent=2) print(square(10)) #100 #想要将一个字符串转换成二进制的整数,可以使用int函数,并且指定base参数为2 n=int('10010',base=2) print(n) #18 basetwo=partial(int,base=2) n=basetwo('10010') print(n) #18
2.单行代码处理全部列表,一个map可抵一套循环
map()函数可以对 一个或多个可迭代对象 的所有元素 进行函数 计算,参数中的函数可以是自己定义的也可以是系统自带的,语法是【map(函数名,可迭代对象,…)】
比如对一个列表内的元素批量乘以二,得到一个新的可迭代对象,就可以先定义一个乘以二的函数,然后再使用map函数
numbers=[6,6,6] def x2(x): return x * 2 result=map(x2,numbers) print(result) #<map object at 0x00000243E022AA10> print(list(result)) #[12, 12, 12]
需要注意的是,map()函数返回的是一个迭代器,只有在需要读取里面的元素时,才开始计算,而这些元素“用完即抛弃”
也就是说,当对map()函数返回的可迭代对象使用一次list()转换成列表后,再次对该可迭代对象使用list()方法,会返回一个空列表,因为在上一次在转换列表时,就对列表里的元素进行过计算并且被释放了
自己写一个跟map()相同功能的函数,大致的思路的是遍历列表内的元素,进行函数计算,然后将计算的结果逐一添加至新列表中
def my_map(f,a): b=[] for i in a: s=f(i) b.append(s) return b
3.lambda表达式短小精悍,可匿名可传参灵活自如
lambda是Python中的一个关键字,可以用于创建一个匿名函数(没有函数名),可以接受任意数量的参数(包括0个,表达式可以写自定义命令),但只有一个表达式,冒号:后面的计算结果就是return的结果,语法格式是【lambda 参数:单行表达式】
比如,想要定义一个函数,功能是返回两个参数的和,一般的写法是这样的:
def add(x,y):
return x+y
用lambda的写法是这样的【add=lambda x,y:x+y】
lambda的优点是可以作为一个匿名函数在其他函数中使用,比如sorted、map等,例如,如果你想要对一个字符串列表中的元素,按照字符串长度来进行排序,可以写成:
words=['hello666','world','python','lambda233'] s=sorted(words,key=lambda x:len(x)) print(s) #['world', 'python', 'hello666', 'lambda233']
lambda虽然定义了一个函数,但却没有函数名,可以把lambda表达式复制给变量,相当于函数名
a=[1,2,3] from math import sin my_sin=lambda x:round(sin(x),2) b=map(my_sin,a) print(list(b)) #[0.84, 0.91, 0.14]
4.reduce席卷容器,利滚利通吃全局
从Python 3开始,reduce()函数被移动到了functools模块中,因此使用该函数需要先【from functools import reduce】
reduce()的基本语法是【reduce(函数,容器,初始值】
其中,function是一个接收两个参数的函数,reduce()通过该函数来处理序列中的元素;
sequence指的是序列、列表等,reduce()会连续调用指定的函数,遍历式的对该序列中的元素一个一个进行计算,
initial为可选参数,如果提供了该参数,那么它将处理第一个序列元素之前放置在计算开始的位置
如果指定了初始值,那么第一次执行时,交给函数的参数为初始值与容器中的第一个元素,
如果不设置初始值,则第一次执行时,交给函数的参数是容器的第一个和第二个元素
计算过程是,将序列中的前两个元素,根据函数进行计算后,得到的结果作为指定函数的第一个参数,序列中的下一个参数作为函数的第二个参数,再次运算,知道序列中的元素被遍历结束位置
from functools import reduce def my_add(x,y): return x+y a=reduce(my_add,[1,2,3]) print(a) #6
一些场景会需要设置初始值,比如计算一个列表中所有数值的平方的和
from functools import reduce def sq_add(x,y): return x + y**2 #1**2+2**2+3**2应该等于14 a=reduce(sq_add,[1,2,3],0) print(a) #14
以上代码,结合lambda可以更为精简
from functools import reduce #1**2+2**2+3**2应该等于14 a=reduce(lambda x,y:x+y**2,[1,2,3],0) print(a) #14
from functools import reduce #抽取一个有多个字符串元素构成的列表中,每个元素的第一个字符,组成一个新的字符串 x=['关羽','张飞','赵云','马超','黄忠'] y=reduce(lambda x,y:x+y[0],x,"") print(y) #关张赵马黄
5.递归算法分身有术,搜遍全局路尽方出
递归会调用函数自身(其实是在内存中调用了自己的一个“拷贝”,严格说是指针和“调用栈”,即另一个函数)
def 阶乘(n): if n==1: s=1 else: s=n*阶乘(n-1) return s if __name__=='__main__': a=阶乘(3) print(a)
对于“层次型”问题,比如硬盘上一层层的子目录,如果需要探寻每一层的内容,但又不知道一共有多少层,那么使用递归方式最简单
isinstance()函数可以用来判断某个对象是否属于某个类型,比如isinstance(a, int)可以判断变量a是否属于int
#提取层层嵌套的子列表内的所有元素 x =[ 5 , [2,3,[ 'a', 'b'] ],[[5,8],[ 6,[9,10] ]]] print(x) def 透视(a): for i in a: if not isinstance(i,list): print(i) else: 透视(i) return 透视(x)
#提取层层嵌套的子列表内的所有元素 x =[ 5 , [2,3,[ 'a', 'b'] ],[[5,8],[ 6,[9,10] ]]] def 透视(a,r): for i in a: if not isinstance (i,list): r.append(i) else: 透视(i,r) return r m=透视(x,[]) print(m) #[5, 2, 3, 'a', 'b', 5, 8, 6, 9, 10]
此处为语雀视频卡片,点击链接查看:[12.5]–第四十六回 递归算法分身有术,搜遍全局路尽方出.mp4
6.装饰器做改革精通世故,新人进旧人留和谐相处
此处为语雀视频卡片,点击链接查看:[12.6]–第四十七回 装饰器做改革精通世故,新人进旧人留和谐相处.mp4
总结
此处为语雀视频卡片,点击链接查看:[13.1]–提高篇结语:学问不可有遗力,编程功夫今始成.mp4