函数式编程
高阶函数
map()
map接受一个函数和一个可迭代对象(Iterable),返回一个map对象(Iterator)
def f(x):
return x*x
list(map(f, [1,2,3]))
#1,4,9
reduce()
reduce接受一个函数(这个函数只能接受两个参数)和一个可迭代对象(Iterable),结果如下:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
filter()
reduce接受一个函数(这个函数返回True或False)和一个可迭代对象(Iterable),返回True保留元素,否则删除元素。返回一个迭代器。看一个素数筛的例子(太牛了):
def _odd_iter():
n = 1
while True:
n = n + 2
yield n
def _not_divisible(n):
return lambda x: x % n > 0
def primes():
yield 2
it = _odd_iter() # 初始序列
while True:
n = next(it) # 返回序列的第一个数
yield n
it = filter(_not_divisible(n), it) # 构造新序列
sorted()
sorted([-1,4,2], key = abs, reverse = True)
参数key是根据key返回结果进行排序,上述例子是按绝对值排序。
返回函数
返回函数就是一个函数的返回值可以是另一个函数对象,且返回的函数内部可以使用母函数的局部变量。
def f():
a = 10
def ff():
return a*a
return ff
注意子函数内部避免使用循环变量!
def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs
f1, f2, f3 = count()
f1() #9
f2() #9
f3() #9
因为都使用了局部变量,fx运行是在count函数之后,count函数运行完时i的值是3,所以三个函数的返回值都是3。
还要注意内层函数要写外层函数的变量时,必须要用 # nonlocal x 声明x是外层变量。
匿名函数
lambda 参数 : 返回值
# 注意不写return
装饰器
语法是在函数定义上一行写上:@装饰器名称,装饰器是一个接受函数参数的函数。
def log(f):
def wrapper(*args, **kw):
print('call %s:' % f.__name__)
return f(*args, **kw)
return wrapper
@log
def sqrt(x):
return x*x
#等价于 sqrt = log(sqrt)
如果装饰器想接收参数,可以写一个函数,这个函数接收参数,并且返回值是一个装饰器。
def log(text):
def decorator(f):
def wrapper(*args, **kw):
print('call %s:' % f.__name__)
return f(*args, **kw)
return wrapper
return decorator
@log('want to say')
def sqrt(x):
return x*x
#等价于 sqrt = log('want to say')(sqrt)
偏函数
偏函数就是把一个函数的某些参数固定后的函数:
int2 = functools.partial(int, base = 2)
#得到将二进制字符串转换为10进制整数的函数等价于
def int2(x, base = 2):
return int(x, base)