Python高阶函数Higher-order function
目录
- Python高阶函数Higher-order function
- 1.函数式编程
- 2.引出高阶函数
- 3.Python内置高阶函数
- 4.`map` 函数
- 5.聚合函数`reduce`
- 6.过滤器`filter`函数
1.函数式编程
函数
是函数Python内建支持的一种封装,我们通过把大段代码拆成函数,式编数通过一层一层的程高函数调用,就可以把复杂任务分解成简单的阶函任务,这种分解可以称之为面向过程的函数程序设计。函数就是式编数面向过程的程序设计的基本单元。
而
函数式编程
——Functional Programming
,程高虽然也可以归结到面向过程的阶函程序设计,但其思想更接近抽象的函数计算。
我们首先要搞明白计算机(
Computer
)和计算(Compute
)的式编数概念。
在计算机的程高层次上,CPU
执行的阶函是加减乘除的指令代码,以及各种条件判断和跳转指令,函数所以,式编数汇编语言
是程高最贴近计算机的语言。
而计算则指数学意义上的计算,越是抽象的计算,离计算机硬件
越远。
对应到编程语言,就是越低级的语言,越贴近计算机,抽象程度低,执行效率高,比如
C
语言;越高级的语言,越贴近计算,抽象程度高,执行效率低,比如Python
语言。
函数式编程就是一种抽象程度很高的编程范式。
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
Python
对函数式编程提供了部分支持。由于Python
允许使用变量,因此,Python
不是纯函数式编程语言。
- 变量可以指向函数
例如Python内置求绝对值函数abs()
>>>abs(-5)5>>>f = abs >>>f
可以看见,只写
abs
只是函数本身,而abs(-5)
才是函数调用,实际我们如果需要函数的结果,可以将函数赋值给变量
例如:
>>>i = abs(-5) >>>i 5>>>f = abs >>>f >>>f(-5) 5
将调用函数的结果,赋值给变量
i
,这样变量就可以打印出结果,如果将函数本身赋值给变量f
,那么变量也拥有这个函数的功能,这个变量将指向这个函数,使用变量f ()
来调用函数和直接调用abs()
效果是一样的。
- 函数名也可以是变量
函数是由
def
定义,函数名,括号,括号参数,冒号,函数体组成,那么函数名是什么呢,可以发现,函数名是指向函数的变量,例如abs()
这个函数,可以将abs
看成变量,它指向一个可以求绝对值的函数,如果把abs
指向其他的对象,例如我们给abs
赋值,那看看还会指向求绝对值的函数吗
>>>abs = 5 >>>abs(-5) Traceback (most recent call last): File "", line 1, in abs(-5) TypeError: 'int' object is not callable >>>abs 5
TypeError: 'int' object is not callable
提示,类型错误,int
类型是不可以被调用的,我们看到,abs
这个变量被赋值5
,然后使用abs(-5)
调动函数,发现异常,此时abs
变量指向的不是函数,而是一个int
类型的5
,实际上,我们工作或是开发中写代码,是不能这么写的,由此可以看出函数名其实就是变量。
注意:由于 abs
函数实际上是定义在 import builtins
模块中的,所以要让修改 abs
变量的指向在其它模块也生效可以使用。
import builtins builtins.abs = 10
2.引出高阶函数
上面的例子,函数可以传参数,而函数名可以做变量,那我们函数里面的参数也可以为函数名。
代码中的total
为高阶函数
# -*- coding: utf-8 -*-# @File : 引出高阶函数.py# @author: Flyme awei # @email : Flymeawei@163.com# @Time : 2022/8/21 10:00def fun(i): return i * 2def total(x, y, fun): return fun(x) + fun(y)add_sum = total(1, 2, fun)print(add_sum) # 6
下面代码test
称为高阶函数
# -*- coding: utf-8 -*-# @File : 高阶函数.py# @author: Flyme awei # @email : Flymeawei@163.com# @Time : 2022/8/21 10:12def fac(n): # 定义一个递归函数计算阶乘 if n == 1: # 递归终止条件 return 1 else: # 在test()函数的函数体内调用该本身 return n*fac(n-1) # 递归调用def test(list_, fun): # 将函数fac本身作为参数传进来,test称为高阶函数 new_list = [] for x in list_: new_list.append(fun(x)) print(new_list)ls = [1, 2, 3, 4, 5, 6, 7]test(ls, fac) # 调用函数test 并把参数lst和fac传入
3.Python内置高阶函数
# -*- coding: utf-8 -*-# @File : 内置高阶函数.py# @author: Flyme awei # @email : Flymeawei@163.com# @Time : 2022/8/21 14:10from functools import reduce'''1.map函数:把一个可迭代对象中的每个元素转换为一个新的对象,最后返回一个新的可迭代对象'''# map(fun, iterables)lst = [1, 2, 3, 4, 5]ite = map(lambda x: x ** 2, lst)print(ite) #
4.map
函数
map()
函数,把一个可迭代对象中的每一个元素换成一个新的对象,最终返回一个迭代器
。
Python内置map()
函数:
class map(object): """ map(func, *iterables) -->map object Make an iterator that computes the function using arguments from each of the iterables. Stops when the shortest iterable is exhausted. """ def __getattribute__(self, *args, **kwargs): # real signature unknown """ Return getattr(self, name). """ pass def __init__(self, func, *iterables): # real signature unknown; restored from __doc__ pass def __iter__(self, *args, **kwargs): # real signature unknown """ Implement iter(self). """ pass @staticmethod # known case of __new__ def __new__(*args, **kwargs): # real signature unknown """ Create and return a new object. See help(type) for accurate signature. """ pass def __next__(self, *args, **kwargs): # real signature unknown """ Implement next(self). """ pass def __reduce__(self, *args, **kwargs): # real signature unknown """ Return state information for pickling. """ pass
map()
函数的返回值:
map(func, *iterables) -->map object
参数详解:
"""func:代表传入参数为函数,这里的函数指定指向函数的函数名*iterables:代表参数指定的可迭代的返回值:返回处理好的数据 map()函数:是将传入的func函数作用于可迭代的数据里的面每个元素,并将处理好的新的结果返回"""
代码实现
# -*- coding: utf-8 -*-# @File : map函数.py# @author: Flyme awei # @email : Flymeawei@163.com# @Time : 2022/8/21 10:03lst = [1, 2, 3, 4, 5]ite = map(lambda x: x**2, lst)print(ite) #
5.聚合函数reduce
reduce()
函数,把一个可迭代对象中的每个元素做聚合处理,最终返回一个聚合之后的值.
functools
函数reduce()
def reduce(function, sequence, initial=_initial_missing): """ reduce(function, sequence[, initial]) ->value Apply a function of two arguments cumulatively to the items of a sequence, from left to right, so as to reduce the sequence to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). If initial is present, it is placed before the items of the sequence in the calculation, and serves as a default when the sequence is empty. """ it = iter(sequence) if initial is _initial_missing: try: value = next(it) except StopIteration: raise TypeError("reduce() of empty sequence with no initial value") from None else: value = initial for element in it: value = function(value, element) return valuetry: from _functools import reduceexcept ImportError: pass
reduce
函数的参数与返回值:
注意使用reduce
函数时需要先导入,reduce
函数是在 functools
模块里面
from functools import reducereduce(function, sequence[, initial]) ->value# 参数详解"""function:一个有两个参数的函数 sequence:是一个序列,是一些数据的集合,或者是一组数据,可迭代对象 initial:可选,初始参数 返回值:返回函数计算的结果 reduce()函数,使用function函数(有两个参数)先对集合中的sequence第 1、2 个元素进行操作,如果存在 initial参数,则将会以sequence中的第一个元素和initial作为参数,用作调用,得到的结果再与sequence中的 下一个数据用 function 函数运算,最后得到一个结果。"""
代码实现:
# -*- coding: utf-8 -*-# @File : 聚合函数reduce.py# @author: Flyme awei # @email : Flymeawei@163.com# @Time : 2022/8/21 12:48from functools import reducelst = [1, 2, 3, 4, 5]va = reduce(lambda x, y: x+y, lst) # 求累加print('s =', va)def max_(x, y): if x >y: return xmax1 = reduce(max_, iter((3, 2))) # 比较大小求大值print(f'max = { max1}')
6.过滤器filter
函数
filter()
函数 把一个可迭代对象中的元素做过滤操作,如果func
返回值为True
则留下,否则过滤掉。
Python内置的
filter()
函数用于过滤序列,和map()
类似,filter()
也接收一个函数和一个序列,但是不同的是filter()
把传入的函数依次作用于每个元素,然后根据返回值是True
还是False
决定元素的保留与丢弃。
Python内置函数filter()
class filter(object): """ filter(function or None, iterable) -->filter object Return an iterator yielding those items of iterable for which function(item) is true. If function is None, return the items that are true. """ def __getattribute__(self, *args, **kwargs): # real signature unknown """ Return getattr(self, name). """ pass def __init__(self, function_or_None, iterable): # real signature unknown; restored from __doc__ pass def __iter__(self, *args, **kwargs): # real signature unknown """ Implement iter(self). """ pass @staticmethod # known case of __new__ def __new__(*args, **kwargs): # real signature unknown """ Create and return a new object. See help(type) for accurate signature. """ pass def __next__(self, *args, **kwargs): # real signature unknown """ Implement next(self). """ pass def __reduce__(self, *args, **kwargs): # real signature unknown """ Return state information for pickling. """ pass
参数列表:
filter(function, iterable)"""function:判断函数。 iterable:序列,(可迭代对象)。 返回值:返回列表 filter函数,序列(可迭代对象)的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返 回 True 的元素放到新列表中"""
filter
函数实现过滤奇数:
# -*- coding: utf-8 -*-# @File : filter函数.py# @author: Flyme awei # @email : Flymeawei@163.com# @Time : 2022/8/21 13:06def not_odd(num): return num % 2 == 0# 过滤奇数new_lst = filter(not_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])print(list(new_lst))
这里定义了一个函数
not_odd
,不是奇数的函数,这个函数,只有当参数为2的整数倍时返回True
。
这里
filter
函数的两个参数第一个是过滤方法,第二个是需要过滤的列表,将列表里面的元素依次带入函数中进行运算,得到的结果如果为True
时,将此结果作为新的filter
对象保留,等待函数里面的列表执行完成后,返回最终的值,这里的值为列表
,也就是过滤掉了False
的数据或元素。
filter
函数过滤操作
# -*- coding: utf-8 -*-# @File : filter函数.py# @author: Flyme awei # @email : Flymeawei@163.com# @Time : 2022/8/21 13:06# filter 把一个可迭代对象中的元素做过滤操作,若果func返回值为True是留下,否则过滤掉staff = [ { 'name': '张三', 'age': 18, 'salary': 2000}, { 'name': '李四', 'age': 20, 'salary': 4000}, { 'name': '麻子', 'age': 22, 'salary': 6000}]# 过滤留下大于18岁的员工lst_age = filter(lambda x: x['age'] >18, staff)print(list(lst_age))# 过滤留下工资大于4000的员工lst_salary = filter(lambda x: x['salary'] >4000, staff)print(list(lst_salary))