python函数式编程
一、高阶函数
1、变量可以指向函数
>>> f = abs >>> f(-10) 10
2、函数名也是变量,可以被赋值,但一般别这么干
3、传入函数
参数是一个函数---高阶函数
def add(x, y, f): return f(x) + f(y) >>>add(-5, 6, abs) 11
4、map / reduce
①map(函数名,Iterable)
函数作用到Iterable的每一个元素上,返回一个Iterator
>>> def f(x): ... return x * x ... >>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> list(r) [1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])) ['1', '2', '3', '4', '5', '6', '7', '8', '9']
②reduce(函数,序列)
reduce把结果继续和序列的下一个元素做累积计算
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
>>> from functools import reduce
>>> def fn(x, y):
... return x * 10 + y
...
>>> reduce(fn, [1, 3, 5, 7, 9])
13579
## 字符串转换成数字----int()
from functools import reduce DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9} def char2num(s): return DIGITS[s] def str2int(s): return reduce(lambda x, y: x * 10 + y, map(char2num, s))
③filter()----过滤序列
函数作用于序列的每一个元素,函数返回值为True // False ,返回True的元素保留,返回False的元素过滤
def is_odd(n): return n % 2 == 1 list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])) # 结果: [1, 5, 9, 15]
④sorted()---排序算法
1)数字排序
>>> sorted([36, 5, -12, 9, -21]) [-21, -12, 5, 9, 36]
##按绝对值排序 >>> sorted([36, 5, -12, 9, -21], key=abs) [5, 9, -12, -21, 36]
2)字符串排序
按ASCII的大小,大写字母在前
>>> sorted(['bob', 'about', 'Zoo', 'Credit']) ['Credit', 'Zoo', 'about', 'bob']
忽略大小写
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower) ['about', 'bob', 'Credit', 'Zoo']
3)反向排序
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True) ['Zoo', 'Credit', 'bob', 'about']
二、返回函数
1、函数作为返回值
def lazy_sum(*args): def sum(): ax = 0 for n in args: ax = ax + n return ax return sum >>> f = lazy_sum(1, 3, 5, 7, 9) >>> f <function lazy_sum.<locals>.sum at 0x101c6ed90> >>> f() 25
2、闭包
返回函数不要引用任何循环变量,或者后续会发生变化的变量。
三、匿名函数(只能有一个表达式)
lambda x:x*x
x是参数
x*x是返回值
lambda x:x*x ##就等于 def f(x): return x*x
①匿名函数赋给一个变量
>>> f = lambda x: x * x >>> f <function <lambda> at 0x101c6ef28> >>> f(5) 25
②匿名函数作为返回值
def build(x, y): return lambda: x * x + y * y
四、装饰器(decorator)
decorator可以增强函数的功能
import functools
##定义一个decorator def log(func): ##参数是一个函数
@functools.wraps(func) ##相当于wrapper.__name__ = func.__name__ def wrapper(*args, **kw): ##可以接受任意参数的调用 print('call %s():' % func.__name__) return func(*args, **kw) return wrapper ##返回值也是一个函数 @log ##声明decorator,相当于执行 now = log(now) def now(): print('2015-3-25') now() ##结果 call now(): 2015-3-25
import functools
##定义一个传入参数的decorator def log(text): ##传入参数 def decorator(func): ##传入函数
@functools.wraps(func) ##相当于wrapper.__name__ = func.__name__ def wrapper(*args, **kw): print('%s %s():' % (text, func.__name__)) return func(*args, **kw) return wrapper return decorator ## 调用decorator,相当于now = log('execute')(now) @log('execute') def now(): print('2015-3-25') now() ## 执行结果: execute now(): 2015-3-25
五、偏函数(Partial function)
functools.partial把一个函数的某些参数给固定住(也就是设置默认值)
当函数的参数个数太多,可以创建偏函数,固定部分参数
>>> import functools >>> int2 = functools.partial(int, base=2) ##字符串转换为二进制数字 >>> int2('1000000') 64 >>> int2('1000000', base=10) ##调用时重新定义base值也可以 1000000
max2 = functools.partial(max, 10) max2(5, 6, 7) ##实际上是max(10,5,6,7)