python 函数高级话题
递归函数
递归是颇为高级的话题,它在Python中相对少见。然而,它是一项应该了解的有用的技术,因为它允许程序遍历拥有任意的、不可预知的形状的结构。递归甚至是简单循环和迭代的替换,尽管它不一定是最简单的或最高效的一种。
用递归求和
让我们来看一些例子。
要对一个数字列表(或者其他序列)求和,我们可以使用内置的sum函数,或者自己编写一个更加定制化的版本。这里是用递归编写的一个定制求和函数的示例:
def mysum(L):
if not L:
return 0
else:
return L[0]+ mysum(L[1:])
#调用自身
print(mysum([1,2,3,4,5,6]))
第一次:L=[1,2,3,4,5,6]
L[0]=1,|1=L[1:]=[2,3,4,5,6]
第二次 :L=|1=[2,3,4,5,6]
L[0]=2 L[1:]=[3,4,5,6]
匿名函数:lambda
lambda 表达式
lambda 的一般形式是关键字lambda,之后是或多个参数(与一个def 头部内用括号括起来的参数列表极其相似),紧跟的是一个冒号,之后是一个表达式,即:
lambda paral ,para2,...paraN :expression using paras
- lambda是一个表达式,而不是一个语句。因为这一点,lambda能够出现在Python语法不允许def出现的地方——例如,在一个列表常量中或者函数调用的参数中。此外,作为一个表达式,lambda返回了一个值(一个新的函数),可以选择性地赋值给一个变量名。相反,def语句总是得在头部将一个新的函数赋值给一个变量名,而不是将这个函数作为结果返回。
- 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))
使用lambda 表达式到相同的效果,通过明确地结果赋值给一个变量名,之后就能够沟通
过这个变量名调用这个函数。
add = lambda x,y,z:x + y +z
print(add(1,2,3))
这里地add 被赋值给一个lambda 表达式创建的函数对象,这也就是def 所完成的任务,只不过def 的赋值是自动进行的。
默认参数也能够在lambda 参数中使用,就像在def 中使用一样。
f = (lambda a ="Tom ",b ="loves",c="python":a+b+c)
print(f())
print(f('loves'))
print(f('Lucy','like',c ="python"))
高阶函数
高阶函数:把一个函数名,以实参的形式,传给这个函数的形参,这个函数就称为高阶函数。
比如下面的形参c 对应的实参是一个函数名abs
def add(a,b,c):
return c(a)+c(b)
add_value=add(-9,1,abs)
print(add_value)
最正确的高阶函数解释
满足下面两个条件之一,就可以名称为高阶函数:
1.把一个函数名当做一个参数,传给另外一个函数
返回值中包含函数名(不修改函数的调用方式)
import time
def bar():
time.sleep(1)
print('函数bar')
def test1(func):
start_time=time.time()
func()
stop_time=time.time()
print("这个函数的运行时间是 %s"%(stop_time-start_time))
test1(bar)
python 中常见的高阶函数
filter
功能 filter 的功能是过滤掉序列中不符合函数条件的元素,当序列中要删减元素可以用某些函数描述时,就应该想起filter函数。
例子:
>>> x=[1,2,3,4,5]
>>> y=filter(lambda x:x%2==0,x)
>>> y
<filter object at 0x000001E3664F8DD8>
>>> list(y)
[2, 4]
>>>
调用
filter(function,sequence)
function可以时匿名函数或者自定义函数,
x= [1,2,3,4,5]
def is_odd(n):
return n%2==1
print(list(filter(is_odd,x)))
map
功能
求一个序列或者多个序列进行函数映射之后的值,就该想到map 这个函数,它是python 自带的函数,py3返回的是迭代器 ,同filter ,需要进行列表转换
.调用
map(function,iterable1,iterable2)
function中的参数值不一定是一个x,也可以是x和y,甚至多个;后面的iterable表示需要参与function 运算中的参数值有几个参数值就传入几个 iterable
>>> x=[1,2,3,4,5]
>>> y=[2,3,4,5,6]
>>> z=map(lambda x, y:x*y+2,x,y)
>>> z
<map object at 0x000001C297448E48>
>>> list(z)
[4, 8, 14, 22, 32]
>>>
rerduce
功能
对一个序列进行压缩运算,得到一个值。但是reduce在python 2时候是内置函数
到了python 3移动了function 模块,所以使用之前需要 from functools
import reduce
调用
reduce(function ,iterable[,initial]),
其中function 必须传入两个参数,iterable可以是列表或者元素
>>> from functools import reduce
>>> y=[2,3,4,5,6]
>>> z=reduce(lambda x,y: x+y,y,100)
>>> z
120
>>> y
[2, 3, 4, 5, 6]
>>>
apply
功能
是pands中的函数,应用对象为pandas中的DateFrame或者Series 大致有两个方面的功能:二是对pands中的groupby 之后的聚合对象apply函数
调用
apply (function,axis),function表明所使用的函数,axis表明对行或者列做运算
zip
功能
zip()函数用于将可迭代对象作为参数,将对象中的元素打包成一个个元组
然后返回有这些元组组成的对象。
如果各个可迭代对象的元素个数不一致,则返回的对象长度与最大短的可迭代对象相同。
利用* 号操作符 ,与zip相反,进行解压。
调用
zip(iterable1,iterable2)
iterable-----一个或多个可迭代对象(字符串,列表,元组,字典)
python2中直接返回一个由组组成的列表,python 3中返回的是一个对象如果想要得到列表,可以用list()函数进行转换。
>>> a=[1,2,3]
>>> b=[4,5,6]
>>> c=[4,5,6,7,8]
>>> zipTest=zip(a,b)
>>> zipTest
<zip object at 0x000002665EC6E5C8>
>>> list(zipTest)
[(1, 4), (2, 5), (3, 6)]
>>> list(zip(a,c))
[(1, 4), (2, 5), (3, 6)]
>>> zipT=zip(a,b)
>>> list(zip(*zipT))
[(1, 2, 3), (4, 5, 6)]
>>>
def formatation(seq):
return seq[0].upper()+ seq[1:].lower()
sr =['hunan',"hello","I Love YOU" ]
print(list(map(formatation,sr)))
def palindrome(n):
rev_n =int (str(n))[::-1]
if rev_n==n:
return rev_n
print(filter(palindrome,range(1,10000)))