在Python中,变量可以指向函数,函数的参数能接收变量,一个函数可以接收另一个函数作为参数,这种函数称之为高阶函数。Python内建的高阶函数主要有map/reduce、filter和sorted等。

  • map/reduce

map()函数接收两个参数,一个是函数,一个是Iterable(可迭代对象),map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator(迭代器)返回。例如:

def f(x):
    return x*x
r=map(f,[1,2,3,4,5])
print(r)  #[1,4,9,16,25]

map()传入的第一个参数是f,即函数对象本身。由于结果r是一个Iterator,Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。

使用循环也可以实现上述计算,map函数事实上是把运算规则抽象了,并简化了代码的编写,在我看来,简化是Python的一大目的和特点。

map()函数类似,reduce()函数也接收两个参数,一个是函数,一个是Iterable(可迭代对象),reduce也是把函数作用到序列的每个元素上;但是与map不同的是,reduce把每次函数计算的结果继续和序列的下一个元素做累积计算,例如:

from functools import reduce
def fn(x,y):
    return x*10+y
sum=reduce(fn,[1,3,5,7,9])
print(sum)    #13579

在上述代码中,reduce把函数fn作用到列表上,首先计算1*10+3得到结果13,之后计算13*10+5得到135,继续计算得到最终结果13579,把一个列表转换成了一个数值。

reduce函数可以和map函数配合,用简洁的代码完成较复杂的计算,例如写出一个把字符串转换为浮点数的函数:

from functools import reduce
def str2float(s):
    n=s.index('.')
    length=len(s)
    tag=1
    if s[0]=='-':
        tag=-1
        s=s[1:n]+s[n+1:]
    else:
        s=s[:n]+s[n+1:]
    DIGITS={'0':0,'1':1,'2':2,'3':3,'4':4,
        '5':5,'6':6,'7':7,'8':8,'9':9}
    def char2num(a):
        return DIGITS[a]
    def f(x,y):
        return x*10+y
    num=reduce(f,map(char2num,s))
    num=num/pow(10,length-1-n)
    return num*tag
  • filter

Python内建的filter()函数用于过滤序列。和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。一个简单的例子:

def is_odd(n):
    return n%2==1
L=list(filter(is_odd,[1,2,3,4,5,6,7,8,9]))
print(L)    #[1,3,4,7,9]

filter()函数返回的也是一个Iterator(迭代器),也就是一个惰性序列。在python教程-廖雪峰关于filter部分有这样一个例子,使用filter求素数:

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)

for n in primes():
    if n<20:
        print(n)
    else:
    break

例子中有这样一句代码:it=filter(_not_divisible(n),it),这里将filter作用在了一个无限序列上,并且循环调用filter时筛选规则不断增加,可以这样理解:对于这个无限序列3,5,7,9,...,在取3时,filter记下了x%3>0的筛选条件;取到5后,filter记下了x%5>0的条件;……;在取到9时,因为9%3=0被去除,生成器计算出下一个数11,11满足条件被取出;……

  • sorted

Python中的sorted()函数也是一个高阶函数,它可以接收一个key函数来实现自定义的排序,key函数将作用于排序对象的每一个元素上,sorted根据key函数返回的结果进行排序。以下为按绝对值大小排序的例子:

L=[36,5,-12,9,-21]
L=sorted(L,key=abs)
print(L)  #[5,9,-12,-21,36]

sorted函数还可以接收第三个参数reverse,设置reverse=True以进行反向排序。