高阶函数 Higher-order function
1. map()
map(fn,Interable)函数接收两个参数,一个是函数,一个是Iterable。返回值是一个Interator。map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回
如下例子。map的返回值是一个Interator对象,通过list()方法转换成一个list集合。
def f(x):
return x*x
r = list(map(f,[1,2,3,4]))
print(r)
2. reduce()
reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算
如下例子:给出序列[1,2,3,4],输出1234
from functools import reduce
r = reduce(lambda x, y: x*10 + y, [1,2,3,4])
print(r)
范例:利用map和reduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456:
from functools import reduce
def str2float(s):
DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
def char2num(str):
return DIGITS[str]
s = s.split(".")
return reduce(lambda x, y: x*10 + y, map(char2num, s[0])) +pow(0.1, len(s[1]))*reduce(lambda x, y: x*10+y, map(char2num, s[1]))
3. filter(fn,arg)
根据传入的函数按条件筛选元素
如下一个筛选回数的例子:
def is_palindrome(n):
s = str(n)
s = s[::-1]
return int(s) == n
output = filter(is_palindrome, range(1, 1000))
4. 匿名函数:
匿名函数关键字:lambda
匿名函数的关键字是lambda,冒号前面是函数的参数。匿名函数的函数体是一个表达式,没有return,表达式的结果就是匿名函数的返回值。
L = list(filter(lambda x:x%2 ==1, range(1, 20)))
print(L)
5. 装饰器(decorator)
在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator. 每个函数都是对象,它上面存在一个name的属性,能获取到函数的名字。
通过name 获取函数的名字:
def top(text):
print(text, top.__name__)
top("这是函数top的名字:") //这是函数top的名字: top
装饰器的定义与使用如下:
import functools
# 创建装饰器:
# 不用传参的装饰器
def log(fn):
@functools.wraps(fn)
def wrapper(*k, **kw):
print("call %s ()" % fn.__name__)
return fn(*k, **kw)
return wrapper
# 装饰器的使用:
@log
def A():
print("这是一个装饰器的例子")
A() // call A () 这是一个装饰器的例子
# 需要传参的装饰器
def logA(text):
def decorator(fn)
@functools.wraps(fn):
def wrapper(*k, **kw):
print("%s call %s ()" % (text, fn.__name__))
return fn(*k, **kw)
return wrapper
return decorator
# 装饰器的使用:
@logA("这是一个带参数的装饰器")
def B():
print("输出结果")
B() // 这是一个带参数的装饰器 call B () 输出结果
在上面的例子中,不带参数的装饰器:
@log
def A():
pass
相当于:
A = log(A)
我们可以看到log()函数运行之后返回的是wrapper函数,这个函数再返回原函数fn时并调用了原函数。此时的A 指向的是wrapper这个函数,A._name_ 等于wrapper,在这种情况下,有些依赖函数签名的代码执行就会出错。所以使用@functools.wraps(fn):把原始函数的name属性的值复制给wrapper函数,以避免有些依赖函数签名的代码执行就会出错。
带参数装饰器:
@logA("这是一个带参数的装饰器")
def B():
pass
相当于:
B = longA('这是一个带参数的装饰器')(B)
后面的过程都和不带参数的都一样。
6. 偏函数
偏函数(Partial function)是python中functools模块提供的一个功能。functools.partial()可以把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
例子:
import functools
int2 = functools.partial(int, base = 2)
value = int2("100")
print(value) // 4