python函数-高级话题
python函数高级话题目录:
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
1.递归函数
递归是颇为高级的话题,它在Python中相对少见。然而,它是一项应该了解的有用的技术,因为它允许程序遍历拥有任意的、不可预知的形状的结构。递归甚至是简单循环和迭代的替换,尽管它不一定是最简单的或最高效的一种。
用递归求和
让我们来看一些例子。
要对一个数字列表(或者其他序列)求和,我们可以使用内置的sum函数,或者自己编写一个更加定制化的版本。这里是用递归编写的一个定制求和函数的示例:
def mysum(L): #print(L) if not L: return 0 else: return L[0]+mysum(L[1:])#调用自身 print(mysum([1,2,3,4,5,6]))
Fibonacci公式:
公式:f(x)=f(x-1)+f(x-2)
举例说明:
list=[] n=int(input("请输入:"))#因为input输出的是str类型,所以需要强转 def sums(n): if n==1: return 1 if n==2: return 1 else: return sums(n-1)+sums(n-2) for i in range(1,n+1): list.append(sums(i)) print(list)
在每一层,这个函数都递归地调用自己来计算列表剩余的值的和,这个和随后加到前面的一项中。当列表变为空的时候,递归循环结束并返回0。当像这样使用递归的时候,对函数调用的每一个打开的层级,在运行时调用堆栈上都有自己的一个函数本地作用域的副本,也就是说,这意味着L在每个层级都是不同的。如上注释部分的print(L),可以运行查看结果。
正如你所看到的,在每个递归层级上,要加和的列表变得越来越小,直到它变为空——递归循环结束。加和随着递归调用的展开而计算出来。
2.匿名函数lambda
lambda表达式
lambda的一般形式是关键字lambda,之后是一个或多个参数(与一个def头部内用括号括起来的参数列表极其相似),紧跟的是一个冒号,之后是一个表达式,即:
lambda para1, para2, ..…, paraN : expression using paras
由lambda表达式所返回的函数对象与由def创建并赋值后的函数对象工作起来是完全一样的,但是1ambda有一些不同之处让其在扮演特定的角色时很有用。
1、lambda是一个表达式,而不是一个语句。因为这一点,lambda能够出现在Python语法不允许def出现的地方——例如,在一个列表常量中或者函数调用的参数中。此外,作为一个表达式,lambda返回了一个值(一个新的函数),可以选择性地赋值给一个变量名。相反,def语句总是得在头部将一个新的函数赋值给一个变量名,而不是将这个函数作为结果返回。
2、lambda的主体是一个单个的表达式,而不是一个代码块。这个lambda的主体简单得就好像放在def主体的return语句中的代码一样。简单地将结果写成一个顺畅的表达式,而不是明确的返回。因为它仅限于表达式,lambda通常要比def功能要小:你仅能够在lambda主体中封装有限的逻辑进去,连if这样的语句都不能够使用。这是有意设计的——它限制了程序的嵌套:lambda是一个为编写简单的函数而设计的,而def用来处理更大的任务。
除了这些差别,def和lambda都能够做同样种类的工作,例如:
def add(x,y,z): return x+y+z print(add(1,2,3)) #结果:6
利用lambda写的例子:
sm = lambda x,y,z : x+y+z print(sm(1,2,3),type(sm)) # 结果6 <class 'function'>
这里的sm被赋值给一个lambda表达式创建的函数对象,这里就是def所完成的任务,只不过def的赋值是自动进行的。
默认参数也能够在lambda参数中使用,就像在def中使用一样。
f=(lambda a='zs',b='ls',c='ww':a+b+c) print(f()) print(f('tom')) print(f('tom','love','zhangsan'))
以上运行结果:
zslsww
tomlsww
tomlovezhangsan
3.高阶函数
高阶函数:把一个函数名,以实参的形式,传给这个函数的形参,这个函数就称为高阶函数。
比如下面的形参c,对应的实参是一个函数abs对象.
def add(a,b,c): return c(a)+c(b) add_value=add(-9,1,abs) # 传入abs函数对象 print(add_value) #运行结果:10
最正确的高阶函数解释
满足下面两个条件之一,就可称之为高阶函数:
-
1.把一个函数名当做一个实参,传给另外一个函数
-
2.返回值中包含函数名(不修改函数的调用方式)
示例1:
import time # 导入时间模块 def bar(): time.sleep(1) # 睡眠1秒钟 print("函数bar") def test1(func):#高阶函数(满足了条件) start_time=time.time() # 函数执行前时间戳 func() # 执行bar()函数,睡眠1秒钟 stop_time=time.time() # 执行函数完时间戳 print("这个函数的运行时间是%s"%(stop_time-start_time)) # 时间差 test1(bar) # 以下结果 # 睡眠一秒钟 # 函数bar # 这个函数的运行时间是1.0007131099700928
示例2:
import time def bar():#高阶函数(满足了条件) time.sleep(1) print("in the bar") def test2(func): print(func) # 打印函数对象地址 return func bar=test2(bar) bar() #运行结果:<function bar at 0x0000021FC3C71E18> # in the bar
4.Python中常见的高阶函数
(1)filter
功能:
filter的功能是过滤掉序列中不符合函数条件的元素,当序列中要删减的元素可以用某些函数描述时,就应该想起filter函数
调用:
filter(function,sequence),function是条件,sequence是序列
function可以是匿名函数或者自定义函数,它会对后面的sequence序列的每个元素判定是否符合函数条件,返回TRUE或者FALSE,从而只留下TRUE的元素;sequence可以是列表,元组或者字符串。
例子1:
x=[1,2,3,4,5] y=filter(lambda x:x%2==0,x)#找出偶数 print(y) #结果:<filter object at 0x000002B97F1F7128> #过滤后的对象 print(list(y))#py3之后filter函数返回的不再是列表而是迭代器,所以需要用list转换 #结果:[2, 4]
例子2:
#普通函数 x=[1,2,3,4,5] def is_odd(n): return n%2==1 #找出所有的奇数 print(list(filter(is_odd,x)))#过滤后的对象转为列表形式输出 #结果:[1, 3, 5]
(2)map
功能:
- 求一个序列或者多个序列进行函数映射之后的值,就该想到map这个函数,它是python自带的函数,py3返回的是迭代器,同filter,需要进行列表转换
调用:
map(function.iterable1,iterable2),
- function中的参数值不一定是一个x,也可以是x和y,甚至多个,后面的iterable表示需要参与function运算中的参数值,有几个参数值就传入几个iterable
例子1:
x=[1,2,3,4,5] y=[2,3,4,5,6] z=map(lambda x,y:(x*y)+2,x,y) print(z) #结果:<map object at 0x000001594F007198> print(list(z)) #结果:[4, 8, 14, 22, 32]
例子2:
#普通函数: def func(x,y): return x*y+2 x=[1,2,3,4,5] y=[2,3,4,5,6] print(list(map(func,x,y))) #结果:[4, 8, 14, 22, 32]
例子3:
#传入3参数也是一样的 def func(x,y,z): return x*y+z x=[1,2,3,4,5] z=y=[2,3,4,5,6] print(list(map(func,x,y,z)))
注:map中如果传入的几个序列的长度不一,那么会依据最短的序列进行计算
(3)reduce
功能:
- 对一个序列进行压缩运算,得到一个值,但是reduce在python2的时候是内置函数,到了python3移到了functools模块,所以使用之前需要 from functools import reduce
调用:
- reduce(function ,iterable)
- 其中function必须传入两个参数,iterable可以是列表或者元组
例子1:
from functools import reduce y=[2,3,4,5,6] z=reduce(lambda x,y:x+y,y) print(z) #结果:20
例子2:
#普通函数: from functools import reduce def tools(x,y): return x+y y=[2,3,4,5,6] print(reduce(tools,y,100))
其计算原理:
先计算头两个元素:f(2, 3),结果为5;
再把结果和第3个元素计算:f(5, 4),结果为9;
再把结果和第4个元素计算:f(9, 5),结果为14;
再把结果和第5个元素计算:f(14, 6),结果为20;
由于没有更多的元素了,计算结束,返回结果20。
(4)apply
功能:
- 是pandas中的函数,应用对象为pandas中的DataFrame或者Series.大致有两个方面的功能:一是直接对DataFrame或者Series应用函数,二是对pandas中的groupby之后的聚合对象apply函数
调用:
apply(function,axis),function表明所使用的函数,axis表明对行或者列做运算。
安装才能使用apply函数
#在cmd命令窗口安装 pip install numpy pip install pandas #画图 pip install matplotlib 画图使用先导包: import matplotlib.pyplot as plt >>> x=[4,7,11,21] >>> plt.plot(x) [<matplotlib.lines.Line2D object at 0x000001F66180BDD8>] >>> plt.show() >>>
例子:
>>> import numpy as np >>> import pandas as pd >>> a=np.random.randint(low=0,high=4,size=(2,4)) >>> a array([[0, 2, 2, 0], [1, 2, 2, 1]]) >>> data=pd.DataFrame(a) >>> data 0 1 2 3 0 0 2 2 0 1 1 2 2 1 >>> data.apply(lambda x:x*10) 0 1 2 3 0 0 20 20 0 1 10 20 20 10 >>>
(5)zip
功能:
zip()函数用于将可迭代对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象。
如果各个可迭代对象的元素个数不一致,则返回的对象长度与最短的可迭代对象相同。
利用*号操作符,与zip相反,进行解压。
调用:
-
zip(iterable1,iterable2,…)
-
iterable 一个或多个可迭代对象(字符串、列表、元组、字典)
python2中直接返回一个由元组组成的列表,python3中返回的是一个对象,如果想要得到列表,可以用list()函数进行转换。
例子1:
x=[2,3,4,5,6] y=[4,5,6,7,8] print(list(zip(x,y))) #结果:[(2, 4), (3, 5), (4, 6), (5, 7), (6, 8)]
例子2:
a=[1,2,3]#此处可迭代对象为列表 b=[4,5,6] c=[5,6,7,8,9] zipTest=zip(a,b) # <zip object at 0x00000115C0C87288>返回的是一个对象 print(zipTest) print(list(zipTest))#转为列表 #结果:[(1, 4), (2, 5), (3, 6)] zipT=zip(a,c) print(list(zip(*zipT)))#解压也使用list进行转换 #结果:[(1, 2, 3), (5, 6, 7)]
例子3:
a = {1: 11, 2: 22} # 此处可迭代对象为字典 b = {3: 33, 4: 44} c = {5: 55, 6: 66, 7: 77} ziptest = zip(a, b, c) print(list(ziptest)) # [(1, 3, 5), (2, 4, 6)] zipt = zip(a, b) print(list(zip(*zipt))) # [(1, 2), (3, 4)]
题目:
1.利使用map()函数,把使用户输入的不规范的英文名字,变为首字母大写,其余小写的规范名字。输入:[hunan, YINGXIAO, COllege],输出:[Hunan, Yingxiao, College]
2.回文数是指从左向右读和从右向左读都是一样的数,例如12321,909。请利使用filter()挑选出1-1000里的回文数:

①.第一题 def formatation(seq): return seq[0].upper()+seq[1:].lower() sr=['hunan','CHANGSHA','collage'] print(list(map(formatation,sr))) #运行结果: #['Hunan', 'Changsha', 'Collage'] ②.第二题 def palindrome(n): rev_n=int(str(n)[::-1]) # 将字符串反转 if rev_n==n: return rev_n print(list(filter(palindrome,range(1,1000)))) #运行结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292, 303, 313, 323, 333, 343, 353, 363, 373, 383, 393, 404, 414, 424, 434, 444, 454, 464, 474, 484, 494, 505, 515, 525, 535, 545, 555, 565, 575, 585, 595, 606, 616, 626, 636, 646, 656, 666, 676, 686, 696, 707, 717, 727, 737, 747, 757, 767, 777, 787, 797, 808, 818, 828, 838, 848, 858, 868, 878, 888, 898, 909, 919, 929, 939, 949, 959, 969, 979, 989, 999]解析
