什么是高阶函数?把函数作为参数传入或把函数做为结果值返回,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。函数式编程的特点:

  • 函数本身可以赋值给变量,赋值后变量为函数;
  • 允许将函数本身作为参数传入另一个函数;
  • 允许返回一个函数。

 

在前面的章节中,我们知道可以用abs()这个函数来得到一个数的绝对值,如:

print('abs(-100):', abs(-100))

以上代码,输出:

abs(-100): 100

 

如果,我们把代码修改下,把abs赋值给一个变量:

f = abs
print(f(-100))

以上代码,输出:

100

可见,abs(-100)是函数调用,而abs是函数本身,要获得函数调用结果,我们可以把结果赋值给变量。函数本身也可以赋值给变量,即:变量可以指向函数,这时变量就获得了函数的功能,如上例中的 f ,直接调用f()和直接调用abs()完全相同。

 

那么函数名是什么呢?函数名其实就是指向函数的变量!对于abs()这个函数,完全可以把函数名abs看成变量,它指向一个可以计算绝对值的函数!

如果把abs指向其他对象,会有什么情况发生?

abs = 10
print(abs(-10))

把abs指向10后,就无法通过abs(-10)调用该函数了!因为abs这个变量已经不指向求绝对值函数而是指向一个整数10!当然实际代码绝对不能这么写,这里是为了说明函数名也是变量。

注:由于abs函数实际上是定义在import builtins模块中的,所以要让修改abs变量的指向在其它模块也生效,要用import builtins; builtins.abs = 10。关于什么是模块,后面会讲到,这里不要去纠结。

 

既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

一个最简单的高阶函数:

def add(x, y, f):
    return f(x) + f(y)

当我们调用add(-5, 6, abs)时,参数x,y和f分别接收-5,6和abs,根据函数定义,我们可以推导计算过程为:

x = -5
y = 6
f = abs
f(x) + f(y) ==> abs(-5) + abs(6) ==> 11
return 11

用代码验证下:

def add(x, y, f):
    return f(x) + f(y)

print(add(-5, 6, abs))

 

1、map函数

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

def f(x):
    """
    返回一个数的3次方
    :param x: 数
    :return: 3次方后的结果
    """
    return x**3

r = map(f, [1, 2, 3, 4, 5])

print(list(r))

 以上代码,输出:

[1, 8, 27, 64, 125]

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

 

当然,不需要map()函数,写一个循环,也可以计算出结果:

def f(x):
    """
    返回一个数的3次方
    :param x: 数
    :return: 3次方后的结果
    """
    return x**3

L = []
for n in [1, 2, 3, 4, 5]:
    L.append(f(n))

print(L)

执行后,结果是一样的,但这样的写法,我们并不能直观的知道f()是作用在列表的所有元素上,并返回一个列表,我们必须读了源代码后才知道。

所以,map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x3,还可以计算任意复杂的函数,比如,把这个list所有数字转为字符串:

print(list(map(str, [1, 2, 3, 4, 5])))

以上代码,输出:

['1', '2', '3', '4', '5']

 

当然,更多的时候我们也会配合lambda来使用,如:

r = map(lambda x: x**3, [1, 2, 3, 4, 5])

print(list(r))

 以上代码,输出:

[1, 8, 27, 64, 125]

 

 

2、reduce函数

reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

 对一个序列求和,就可以用reduce实现:

from functools import reduce

def add(x, y):
    return x + y

print('reduce(add, [1, 3, 5, 7, 9]) = ', reduce(add, [1, 3, 5, 7, 9]))

 以上代码,输出:

reduce(add, [1, 3, 5, 7, 9]) =  25

当然求和运算可以直接用Python内建函数sum(),思考:如何把序列 [1, 2, 3, 4, 5] 转化为整型的 12345 ,下面给出代码但请尽可能自己先写出

from functools import reduce

def f(x, y):
    return x*10 + y

res = reduce(f, [1, 2, 3, 4, 5])

print(res)
View Code

相关文章:

  • 2018-01-31
  • 2022-12-23
  • 2020-01-05
  • 2021-12-10
  • 2021-07-13
  • 2021-11-03
  • 2022-01-30
猜你喜欢
  • 2021-08-15
  • 2021-05-23
  • 2022-12-23
  • 2022-01-07
  • 2021-06-17
  • 2021-08-18
  • 2021-06-10
相关资源
相似解决方案