1. 高阶函数
1. 高阶函数基础
变量可以指向函数
函数名也是变量
高阶函数允许传入函数#!/usr/bin/env python #将函数赋值给变量 A = abs print A(-10) #导入__builtin__模块 import __builtin__ #改变abs变量的指向 __builtin__.abs = 20 #输出abs变量 print abs abs = 30 print abs abs = A print abs(-10) #定义一个高阶函数,入参是函数 def add(x,y,func): return func(x) + func(y) #调用高阶函数 print add(-10,3,abs)
2. map/reduce
map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。
reduce()函数接收两个参数,一个是函数,一个是序列,reduce把前面两个数据通过传入的函数运算得出的结果再与后面一个数据使用传入的函数进行运算,最终返回结果。#!/usr/bin/env python def add(x): return x + 2 #使用map,让list里面每个元素都执行一次add函数,之后返回一个新的list print map(add,[1,2,3]) def sum(x,y): return x + y #使用reduce,先取list里面的第一、二个元素,运行一次传入的函数。得到的结果再与后面的元素结合成参数,运行一次函数,依此类推,最终后返回结果 print reduce(sum,[1,2,3]) #使用reduce和map,定义了一个字符串转换数字的函数 def str2int(s): def fn(x,y): return x * 10 + y def char2num(s): return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s] return reduce(fn,map(char2num,s)) print str2int('1314')
3. filter
接收一个过滤器,用于过滤序列中的元素,只保留过滤器认可的元素
当过滤器返回False时,将删除掉序列中的元素#!/usr/bin/env python #定义一个过滤器,将所有奇数过滤出来 def is_odd(n): return n % 2 == 1 print filter(is_odd,[1,2,3,4])
4. sorted
接收一个比较器,对序列进行排序
#!/usr/bin/env python L = [36,5,12,9,21] print sorted(L) #定义一个比较器 def reversed_cmp(x,y): if x > y: return -1 if x < y: return 1 return 0 print sorted(L,reversed_cmp) #定义一个忽略大小写的字符串比较器 def cmp_ignore_case(s1,s2): u1 = s1.upper() u2 = s2.upper() if u1 < u2: return -1 if u1 > u2: return 1 return 0 print sorted(['bob','about','Zoo'],cmp_ignore_case);
2.函数作为返回值
#!/usr/bin/env python def lazy_sum(*args): #定义一个求和函数,返回给调用者 def sum(): s = 0 for n in args: s = s + n return s return sum #求和没有立即执行,而只是返回了一个函数 f = lazy_sum(1,2,3) #当调用f()时,求和才真正执行 print f()
3.闭包
#!/usr/bin/env python def count(): fs = [] for i in range(1,4): def f1(x): #定义一个闭包函数 def f2(): return x * x return f2 fs.append(f1(i)) return fs f1,f2,f3 = count() print f1() print f2() print f3()
4. 匿名函数lambda
注意,冒号前面的表示参数
#!/usr/bin/env python #定义一个匿名函数,并赋值给了变量f f = lambda x,y: x + y print f(1,2) #定义一个匿名函数,并传给了map函数 print map(lambda x: x + 1,[1,2,3])
5. 装饰器decorator
函数有一个name属性,可以拿到函数的名字
Python内置的functools.wraps可以把原始函数的属性复制到新定义的函数中#!/usr/bin/env python import functools #定义一个不带参数的装饰器,用于输出日志 def log(func): @functools.wraps(func) def wrapper(*args,**kw): print 'call %s():' % func.__name__ return func(*args,**kw) return wrapper #注明此函数需要使用装饰器 @log def now(): print '2015-12-12' #调用now函数,会输出日志 now() print '\n' #定义一个带参数(有默认参数)的装饰器,用于输出日志 def log2(text='--call--'): def decorator(func): @functools.wraps(func) def wrapper(*args,**kw): print '%s %s():' % (text,func.__name__) return func(*args,**kw) return wrapper return decorator #注明now2函数需要使用装饰器 @log2('execute') def now2(): print '2015-12-12' #调用now2函数 now2() #注明now3函数需要使用装饰器(使用装饰器的默认参数) @log2() def now3(): print '2015-12-12' #调用now3函数 now3()
6. 偏函数Partial function
当函数的参数个数太多,可以使用functools.partial,创建一个新函数,这个新函数可以固定原函数的部分参数,从而在调用时更简单。
#!/usr/bin/env python import functools #创建一个偏函数,固定参数base的值为2 int2 = functools.partial(int,base=2) #调用偏函数 print int2('100') def max(x,y): if x > y: return x return y print max(22,10) #定义一个偏函数,固定参数x为22 max2 = functools.partial(max,22) #调用偏函数,此时,x已经被固定为22,固只需要传入y的值为10 print max2(10)