标签:
注:慕课网笔记
高阶函数
1.变量可以指向函数,例如 a=abs 则 a(-10)=10 。
2.一个函数可以接收另外一个函数作为参数 例如 fun1 是一个函数 , 函数fun2(fun1 , L) 可以接收 fun1 作为它的一个参数。
例如:
1:
2: def add(x,y,f)
3: return f(1)+f(2)
4: add(-1,2,abs) ####相当于是 abs(-1)+abs(-2)
3.如果一个函数可以接收另一个函数作为参数,那么这个函数就是高阶函数。
Pyhton 内置高阶函数
1.map()函数
map()接收一个函数f和一个list,通过函数f依次作用于list每一个元素上,
得到一个新的元素并返回。
对于 list [1,2,3,4,5]
如果希望把list每个元素都作平方就可以用map()函数
例:
def f(x):
return x*x
print map(f,[1,2,3,4,5])
2.reduce()函数
reduce()函数接收的参数和 map()类似,一个函数 f,一个list,
但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,
reduce()对list的每个元素反复调用函数f,并返回最终结果值。
###定义一个函数f,接收x和y,返回x和y的和
def f(x,y):
return x+y
#reduce函数调用f
reduce(f,[1,2,3,4,5])
reduce调用顺序为:
f(1,2)=3 f(3,3)=6 f(6,4)=10 f(10,5)=15 因此reduce函数最终返回结果15。
retuce可以接受第三个参数作为计算初始值
例如:
reduce(f,[1,2,3,4,5],100) 则 f(100,1)=101 f(101,2)=103 f(103,4)=107 f(107,5)=121
综上,因此map返回的是一个list 而 reduce 返回的是一个数值
3.filter()
filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False
filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件(true)元素组成的新list。
##利用filter()删除 None 或者空字符串:
def is_not_empty(s):
return s and len(s.strip())>0
filter(is_not_empty,[‘test‘,None,‘‘,‘str‘,‘
‘,‘END‘ ])
结果:[‘test‘,‘str‘.‘END‘]
### s.strip(rm) 删除 s 字符串中开头、结尾处的 rm 序列的字符。
###
当rm为空时,默认删除空白符(包括‘\n‘,‘\r‘,‘\t‘,‘‘)
###用filter()过滤出1~100中平方根是整数的数,即结果应该是:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
import math
def is_sqr(x):
i=int(math.sqrt(x))
return x==i*i
print filter(is_sqr, range(1, 101))
4.sorted()
sorted()函数可对list进行排序,例如:
sorted([36, 5, 12, 9, 21])
[5, 9, 12, 21, 36]
但同时sorted()也是一个高阶函数,它可以根据一个用户自己定义的比较函数来排序。例如
##定义如下的倒序排序函数
def reversed_cmp(x, y):
if x > y:
return -1
if x < y:
return 1
return 0
##调用sorted()函数
sorted([36, 5, 12, 9,
21], reversed_cmp)
[36, 21, 12, 9, 5]
返回函数的函数
Python的函数不但可以返回int、str、list、dict等数据类型,还可以返回函数
例如,定义一个函数 f(),我们让它返回一个函数 g,可以这样写:
def f():
print ‘call f()...‘
#
定义函数g:
def g():
print ‘call g()...‘
# 返回函数g:
return g
我们在函数 f 内部又定义了一个函数 g。由于函数 g 也是一个对象,函数名 g 就是指向函数 g 的变量,
所以,最外层函数 f 可以返回变量 g,也就是函数 g 本身。
返回函数可以把一些计算延迟执行。例如,如果定义一个普通的求和函数
def calc_sum(lst):
return sum(lst)
调用calc_sum()函数时,将立刻计算并得到结果:
>>> calc_sum([1, 2, 3, 4])
10
但是,如果返回一个函数,就可以“延迟计算”:
def calc_sum(lst):
def lazy_sum():
return sum(lst)
return lazy_sum
# 调用calc_sum()并没有计算出结果,而是返回函数:
>>> f = calc_sum([1, 2, 3, 4])
>>> f
<function lazy_sum at 0x1037bfaa0>
# 对返回的函数进行调用时,才计算出结果:
>>> f()
10
由于可以返回函数,我们在后续代码里就可以决定到底要不要调用该函数。
闭包
内层函数引用外层变量然后返回内层函数的情况,称为闭包
闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,
就要确保引用的局部变量在函数返回后不能变。
# 希望一次返回3个函数,分别计算1x1,2x2,3x3:
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count()
#
实际结果是f1()f2()f3()都是9,原因是count()函数返回三个函数,执行完count()之后这三个函数
#
引用的变量i已经变成了3,所以当调用f1()f2()f3()时返回值都是9.
解决方法:
#solution1 :函数fun()它可以正确地返回一个闭包g,g所引用的变量j不是循环变量,因此将正常执行
def count():
fs = []
for i in
range(1, 4):
def fun(i):
def g():
return i*i
return g
fs.append(fun(i))
return fs
f1, f2, f3 = count()
print f1(), f2(), f3()
#solution2 :函数定义时可以获取到i,问题便可解决。而默认参数正好可以完成定义时获取i值
#并且运行函数时无需参数输入的功能,所以在函数f()定义中改为f(m = i),函数f返回值改为m*m即可
def count():
fs = []
for i in
range(1, 4):
def f(m = i):
return m
* m
fs.append(f)
return fs
f1, f2, f3 = count()
print f1(), f2(),
f3()
匿名函数
高阶函数可以接收函数作为参数,有时候我们不需要显示定义函数,直接传入匿名函数更加方便简洁。
前面提到的map()函数可以接收一个函数f和一个list
#lambda是关键字,表示匿名函数,冒号前面的x表示函数参数,这里lambda x:x*x
#实际上就是def(x):
# return x*x
>>>map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])
[1,4,9,16,25,36,49,64,81]
匿名函数返回值就是:后面的表达式的值,而匿名函数仅能有一个表达式,不用写return。
返回函数的时候也可以返回匿名函数:
>>> myabs = lambda x: -x if x < 0 else x
>>> myabs(-1)
1
>>> myabs(1)
1
装饰器
装饰器可以对一个函数、方法或者类进行加工
首先我们自己定义一个sum函数
def sum(a,b)
print a+b
之后我们又希望在原来的基础上加上一个打印输入的功能,像下面这样:
def sum(a,b)
print ("input:",a,‘,‘,b)
print a+b
可以直接修改sum函数的代码,也可以通过装饰器来实现,
def decorator(F):
def
new_F(a, b):
print("input", a, b)
return F(a, b)
return new_F
之后再通过调用装饰器f=decorator(f)
python为我们提供了一个简便的语法
@decorater
def sum(a,b)
print a+b
那么在右面调用sum()函数的时候就可以有打印输入的功能了
上面的例子我们可以看出Python的装饰器实际上就是高阶函数。接收一个函数作为参数返回一个新函数。
不过在编写装饰器的时候一般会写 参数(*args,**kw) 表示接收函数f的任意参数以及 @functools.wraps(f)
来完善装饰器。因为仅仅经过装饰其改造后的函数与原函数相比__name__变量(也就是函数名)也变化了
def decorater(f)
@functools.wraps(f)
def wrapper(*args,**kw):
print ‘call %s ...‘ % f.__name__
return f(*args,**kw)
return wrapper
带参数的decorator
import time
def performance(unit):
def
perf_decorator(f):
def
wrapper(*args,**kw):
t1=time.time()
r=f(*args,**kw)
t2=time.time()
t=
(t2-t1) * 1000 if unit==‘ms‘ else (t2-t1)
‘call %s() in %f %s‘ % (f.__name__,t,unit)
return r
return wrapper
return perf_decorator
@performance(‘ms‘)
def factorial(n):
return
reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)
上面的performance装饰器的功能是打印函数执行的时间,它接受一个参数unit
可以根据传入的参数unit来表示打印时间的单位是ms还是s。
偏函数:
int()函数还提供额外的base参数,默认值为10。如果传入base参数,就可以做 N 进制的转换
假设要转换大量的二进制字符串,每次都传入int(x, base=2)非常麻烦,于是,我们想到,
可以定义一个int2()的函数,默认把base=2传进去,像下面这样:
def int2(x, base=2):
return int(x, base)
functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用
下面的代码创建一个新的函数int2
>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2(‘1000000‘)
64
所以,functools.partial可以把一个参数多的函数变成一个参数少的新函数,少的参数需要在创建时
指定默认值,这样,新函数调用的难度就降低了。
标签:
原文地址:http://www.cnblogs.com/diligent-bird/p/5510403.html