高阶函数
高阶函数(Higher-order function)可接受函数作为参数,也可以把函数作为返回值。
map/reduce:
map(): 接受两个参数, 一个是函数, 一个是数列。map将传入的函数一次作用在数列的每个元素上,将结果作为新的list返回。
>>> def f(x):
return x*x
>>> map(f, [1, 2, 3, 4])
[1, 4, 9, 16]
>>> def add(x, y):
return x+y
>>> reduce(add, [1, 2, 3, 4])
10
使用map/reduce可写出将str转换成int的函数:
>>> def str2int(s):
def fn(x,y):
return x*10+y
return reduce(fn, map(int, s))
>>> str2int('4321')
4321
>>>
sort:
内置排序算法,默认按照从下到大排。
可以定义一个倒排方法,传进sored方法中:
>>> def reversed_cmp(x, y):
if x > y:
return -1
if x == y:
return 0
if x < y:
return 1
>>> sorted([36, 5, 46, 4, 23],reversed_cmp)
[46, 36, 23, 5, 4]
使用sort 对字符串排序,由于内置函数按照ASCII排序,使得小写z在大写A前面,改进:
>>> def cmp_ignore_case(s1, s2):
u1 = s1.lower()
u2 = s2.lower()
if u1 < u2:
return -1
if u1 > u2:
return 1
return 0
>>> sorted(['ABC', 'resA', 'gdEW', 'SGRR'], cmp_ignore_case)
['ABC', 'gdEW', 'resA', 'SGRR']
简单介绍 匿名函数:
匿名函数lambda,冒号前面是传入的参数,冒号后面是仅有的一个表达式,返回值就是该表达式的结果。
>>> map(lambda x: x*x, [1, 2, 3, 4, 5, 6])
[1, 4, 9, 16, 25, 36]
函数作为返回值:
以一个可变参数求和为例子:
>>> def lazy_sum(*args):
def sum():
ax=0
for n in args:
ax = ax + n
return ax
return sum
>>> f = lazy_sum(1, 2, 3, 4, 5)
>>> f
<function sum at 0x0000000002D282E8>
>>> f()
15
在函数lazy_sum中定义了函数sum,当调用lazy_sum时,返回的并不是求和结果,而是求和函数,这称为“闭包”,想要得到结果时,需调用f()
装饰器 decorator
要增强某函数功能,但又不想修改函数定义,在代码运行期间动态增加函数功能的方式就是decorator。
本质上,decorator是一个返回函数的高阶函数。
>>> def log(func):
def wrapper(*args, **kw):
print 'call %s():' %func.__name__
return func(*args, **kw)
return wrapper
>>> @log
def now():
print '2014-3-10'
>>> now()
call now():
2014-3-10
其中,log是一个decorator函数,使用@log放在函数定义前,相当于后面调用now()时执行语句now = log(now)。
调用now()后,首先执行log(now)返回wrapper函数,然后执行wrapper,打印函数名,并且调用原始now()函数。
如果decorator本身需要传参数,那么就需要再定义一个返回decorator的高阶函数:
>>> def log(text):
def decorator(func):
def wrapper(*args, **kw):
print '%s %s():' % (text, func.__name__)
return func(*args, **kw)
return wrapper
return decorator
>>> @log('execute')
def now():
print '2014-3-10'
>>> now()
execute now():
2014-3-10
@log('execute')相当于now = log('execute')(now)
调用过程是:首先执行log('execute'),返回decorator函数,执行参数是now的decorator函数,返回wrapper函数,执行wrapper函数,打印内容并调用原始now()函数。
但现在的函数名为:
>>> now.__name__
'wrapper'
需要加入import functools 以及在定义 wrapper 前加入 @functools.wraps(func)
例如:
>>> import functools
>>> def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print 'call %s():' %func.__name__
return func(*args, **kw)
return wrapper
偏函数
偏函数是functools模块提供的一个功能,主要作用于函数调用时的参数上面。
之前有说过,为了方便使用,函数可以存在一个或多个默认参数。在python自带的的函数的默认参数是已经制定好的,偏函数的使用就可以局部改变函数的默认值。
如 Int() 可以将字符串变为整形,但该函数有一个默认参数base =10 意思是默认字符串为10进制
>>> int('1234', base = 8)
668
如果有大量的需转为整形的2进制数,这样调用比较麻烦,这时可以改为:
>>> def int2(x, base = 2):
return int(x, base)
>>> int2('10000')
16
使用偏函数可以简化为:
>>> import functools
>>> int2 = functools.partial(int, base = 2)
>>> int2('10000')
16