Python函数式编程——高阶函数(Higherorder function)

2023年 7月 12日 76.2k 0

Python函数式编程——高阶函数(Higher-order function)

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:00


def fun(i):
    return i * 2


def 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:12


def 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:10

from functools import reduce


'''
1.map函数:把一个可迭代对象中的每个元素转换为一个新的对象,最后返回一个新的可迭代对象'''
# map(fun, iterables)
lst = [1, 2, 3, 4, 5]
ite = map(lambda x: x ** 2, lst)
print(ite)  # 
for i in ite:
    print(i, end=' ')  # 1 4 9 16 25


'''
2.reduac() 把一个可迭代对象中的每个元素都做聚合处理,返回一个聚合之后的值
from functools import reduce 
reduce(function, sequence[, initial]) -> value'''
# function:一共有两个参数的函数
# sequence:是一个序列,是一些数据的集合,或者是一组数据,可迭代对象
# initial:可选,初始参数 返回值:返回函数计算的结果
va = reduce(lambda x, y: x + y, lst)  # 求累加
print('ns =', va)  # s = 15


def max_(x, y):
    if x > y:
        return x


max1 = reduce(max_, iter((3, 2)))  # 求最大值
print(max1)  # 3


'''
3.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('大于18岁的员工:', list(lst_age))

# 工资大于4000的员工
lst_salary = filter(lambda x: x['salary'] > 4000, staff)
print('工资大于4000的员工:', list(lst_salary))


'''
4.max 和 min'''
# 计算最大工资的员工
print('最高工资的员工:', max(staff, key=lambda x: x['salary']))
# 计算最小年龄的员工
print('最低工资的员工:', min(staff, key=lambda x: x['age']))


'''
5.sorted把一个迭代对象里的每个元素做排序,最终返回一个列表'''
# 根据员工年龄降序排序
list_sorted = sorted(staff, key=lambda x: x['age'], reverse=True)
print('工资降序排序:', list_sorted)

Python函数式编程——高阶函数(Higher-order function)

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:03


lst = [1, 2, 3, 4, 5]
ite = map(lambda x: x**2, lst)
print(ite)  # 
for i in ite:
    print(i, end=' ')
    

Python函数式编程——高阶函数(Higher-order function)

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 value

try:
    from _functools import reduce
except ImportError:
    pass

reduce函数的参数与返回值:

注意使用reduce函数时需要先导入,reduce函数是在 functools模块里面

from functools import reduce
reduce(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:48


from functools import reduce

lst = [1, 2, 3, 4, 5]
va = reduce(lambda x, y: x+y, lst)  # 求累加
print('s =', va)


def max_(x, y):
    if x > y:
        return x


max1 = reduce(max_, iter((3, 2)))  # 比较大小求大值
print(f'max = {max1}')

Python函数式编程——高阶函数(Higher-order function)

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:06


def 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))

Python函数式编程——高阶函数(Higher-order function)

作者:北极的三哈 来源:稀土掘金

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论