Python入门10:高阶函数

news2025/1/15 20:50:27

一、什么是高阶函数

1.1、高阶函数的概念和作用:

        高阶函数是指 接受函数作为参数 或者 返回函数 作为结果的函数。它在函数式编程中是一个重要概念(函数式编程(Functional Programming FP )是一 种编程范式,它将计算视为数学函的求值,并且避免使用可变数据结构和 改变状态的操作。函数式编程的核心思想是将函数作为程序的基本构建块, 强调不可变性和纯函数的使用)。

1.2、高阶函数的特点:

(1)、接受一个或多个函数作为输入参数:这意味着你可以将函数作为参数传 递给另一个函数。

  (2)、返回一个函数作为输出:这意味着函数可以返回另一个函数。

二、当参数为一个函数的情况

案例:

# 需求:定义一个函数,带两个整数类型的参数
# 该函数的功能是把两个 参数整理之后 做求和计算,并把结果返回
非高阶函数的写法:
def my_function(num1,num2):
    # 对传入的两个参数进行平方处理
    new_num1 = num1**2
    new_num2 = num2**2
    # 对处理后的文件进行求和操作,并返回
    return new_num1+new_num2
print(my_function(3,4))

非高阶函数写法的弊端:

        由于题目的需求的不确定性,针对于“参数整理之后”没有明确的规定,在上面的案例中,我们对传入的两个参数进行了平方再求和的操作,但是实际上有些时候,我们不同的用户调用函数时可能进行不同的处理,比如张三要对这两个数字求绝对值再求和呢?就不得吧求平方的代码改为求绝对值的代码,这样的话函数的用途就很有限了。那么我们怎么样设计才能够不管调用者想对他进行什么操作,而不用改变函数体内的代码呢,当然可以,这个时候我们就需要使用函数作为参数实现了。

高阶函数的写法:

1、当行为函数是自定义时:

# 定义行为函数
def do_function(number):
    return number * 10
# 注意:在参数中传入函数时不需要加(),加上小括号,表示的是调用函数,不是参数
def my_function(num1,num2,function):
    """
    :param num1: 传入第一个数字的参数
    :param num2: 传入第二个数字的参数
    :param function: 传入你想要进行的函数操作
    :return: 返回值是对传入的数字进行处理后求和计算
    """
    return function(num1) + function(num2)
# 调用函数:调用函数在传入函数时不需要加(),加上小阔号表示的是调用函数,不是传参
print(my_function(1,2,do_function))

2、当行为函数是内置模块的函数时:

def my_function(num1,num2,function):
    """
    :param num1: 传入第一个数字的参数
    :param num2: 传入第二个数字的参数
    :param function: 传入你想要进行的函数操作
    :return: 返回值是对传入的数字进行处理后求和计算
    """
    return function(num1) + function(num2)

# 导入math模块进行先求根再进行操作
import math
# 对参数进行求平方根再求和
print(my_function(100, 4, math.sqrt))
# 对参数进行阶乘操作后求和
print(my_function(2, 4, math.factorial))

3、传入的函数只有一句话时:可以使用lambda表达式:

# 刚刚求和的函数:
my_function = lambda num1, num2,function: function(num1) + function(num2)
# 行为参数:
do_function = lambda number: number * number
# 调用函数并输出
print(my_function(1, 2, do_function))

4、总结:

(1)、当定义函数时,函数的参数是一个函数,那么定义的这个函数可以称为 高阶函数。
(2)、调用高阶函数时需要特别注意,由于高阶函数中参数类型是个函数,因此在进行调用时,我们只需要传递函数的名字即可,而不是进行函数调用。
(3)、函数作为参数的类型时,可以是内置的函数,如abs ,也可以是其它模块 下的函数,如sqrt ,也可以是自定义的函数,如 num_num ,像上面代码中 num_num函数的函数体只有一行代码,可以用 lambda 表达式的方式写。
5、当参数有两个函数时:
# 传入math模块
import math
# 定义高阶函数
def self_fuc(num1,num2,function1,function2):
# 对第一个参数乘10,对第二个参数阶乘操作,再求和
    return function1(num1) + function2(num2)
# 调用函数:传入两个行为函数
print(self_fuc(1, 2, lambda x: x * 10, math.factorial))

三、当返回值是一个函数的时候

def out_function(*args):
    print("我是外部函数!")
    def inner_function(number):
        sum = 0
        for i in args:
            sum += i
        print("我是内部函数里面的number,传入的值为:",number)
        return f'累加结果为:{sum}'
    # 返回值为内部函数,不需要加(),加上表示调用函数
    return inner_function
# 返回为地址:因为返回的内部函数的名字,打印的为地址
print(out_function(2,3,4))
# 外部函数返回为内部函数的inner_function,后面的括号表示的inner_function(666)
print(out_function(2,3,4)(666))

四、常见的Python内置高阶函数

4.1、map函数    

map() 函数 接受一个函数 一个可迭代对象 作为参数,将函数应用于可迭代 对象的每个元素,并 返回一个新的迭代器
参数 1 :要传入进行处理的函数名
参数 2 :一个可以操作的数据集或者序列或者是可迭代对象
简单点可以理解为:把参数 2 中的每个元素拿出来,放到参数 1 的函数中去处 理一遍,再返回到一个新的数据集中去。
案例:
# 导入math模块
import math
# 定义一个可迭代数据
numbers = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# 调用高阶函数map()并且传入参数,使用sqrt函数对每个数据求算数平方根
map_res = map(math.sqrt, numbers)
print(map_res)
# 由于map函数返回是一个迭代器对象,直接打印的话不够直观
# 因此使用list函数给它进行转化一下输出更直观
print(list(map_res))

4.2、reduce函数

reduce() 函数位于 functools 模块中,它接受 一个函数 和一个 可迭代对 象 作为参数, 函数必须接受两个参数 。reduce() 会将函数依次应用于可迭代 对象的元素, 返回一个单一的结果
# 导入包
import functools
def my_fc(x,y):
    print("x的值:",x)
    print("y的值:",y)
    return x + y
# 定义要操作的可迭代数据
my_list = [1,2,3,4,5]
# 调用reduce函数
res = functools.reduce(my_fc,my_list)
print(res)

4.3、filter函数

filter() 函数接受一个函数和一个可迭代对象作为参数。 filter() 过滤 掉那些函数返回False 的元素,返回一个新的迭代器
# 定义行为参数
def my_function(x):
    if x > 10:
        return x
# 定义要处理的可迭代数据
num_list = [1,2,3,4,5,10,20,30,40,50]
# 调用filter函数
res = filter(my_function, num_list)
print(list(res))

4.4、sorted函数

sorted() 函数可以对任何可迭代对象进行排序,并返回一个新的列表。它接受一个key 参数,该参数可以是一个函数,用于指定排序的依据。
stu = [
    {"name" : "jack","age" : 20},
    {"name" : "tom","age" : 19},
    {"name" : "lucy","age" : 19},
]
# 先根据年龄排序,如果年龄相同,再根据名字排序
new_stu = sorted(stu, key=lambda x:(x["age"],x["name"]),reverse=True)
print(new_stu)

4.5、any函数和all函数

any() :如果可迭代对象中至少有一个元素为 True ,则返回 True
all() :如果可迭代对象中所有元素都为 True ,则返回 True
numbers = [1,2,3,4,5,0]
# 是否有非0元素:
is_true = any(numbers)
print(is_true)
# 是否没有0元素
is_true1 = all(numbers)
print(is_true1)

4.6、zip函数

zip() 函数接受多个可迭代对象作为参数,将它们组合成一个迭代器,每个元素是一个元组,包含来自每个可迭代对象的对应元素。
names = ("李小妹","帅哥","张三","tom")
ages = [23,24,20]
# 组合成一个列表
res = list(zip(names,ages))
print(res)
# 组合成一个字典
res1 = dict(zip(names,ages))
print(res1)
# 组合成一个元组
res2 = tuple(zip(names,ages))
print(res2)
 # 如果合成后还有一个可迭代对象的元素没有匹配,那么将会自动舍弃

4.7、enumerate函数

enumerate() 函数接受一个可迭代对象和一个可选的起始索引,返回一个迭代器,每个元素是一个元组,包含索引和对应的值。
names = ["李小妹","帅哥","张三","tom"]
res = enumerate(names,start=0)
# 只能转化为list
print(list(res))
print(dict(res))
print(tuple(res))
print(set(res))

五、高阶函数的练习

假设你是一家电商公司的数据分析师,需要对销售数据进行分析。你有一个 包含多个订单信息的列表,每个订单信息是一个字典,包含订单ID 、客户ID、订单金额和订单日期。你需要完成以下任务:
1. 筛选出订单金额大于 1000 元的订单
2. 计算每个订单的折扣金额(折扣率为 10%
3. 计算所有订单的总金额
4. 找出订单金额最高的订单
任务要求:
1. 筛选出订单金额大于 1000 元的订单
使用 filter 函数筛选出订单金额大于 1000 元的订单。
将结果存储在变量 high_value_orders 中。
2. 计算每个订单的折扣金额(折扣率为 10%
使用 map 函数计算每个订单的折扣金额。
将结果存储在变量 discounted_orders 中,每个订单字典中增加
一个 discount 键,值为折扣金额。
3. 计算所有订单的总金额
使用 map 函数提取所有订单的金额。
使用 reduce 函数计算所有订单的总金额。
将结果存储在变量 total_amount 中。
4. 找出订单金额最高的订单
使用 max 函数和 key 参数找出订单金额最高的订单。
将结果存储在变量 highest_amount_order 中。
from functools import reduce
# 数据
orders = [
    {"order_id": 1, "customer_id": 101, "amount": 1200,"date": "2024-01-01"},
    {"order_id": 2, "customer_id": 102, "amount": 800,"date": "2024-01-02"},
    {"order_id": 3, "customer_id": 103, "amount": 1500,"date": "2024-01-03"},
    {"order_id": 4, "customer_id": 104, "amount": 950,"date": "2024-01-04"},
    {"order_id": 5, "customer_id": 105, "amount": 1800,"date": "2024-01-05"}
]
# 1. 筛选出订单金额大于1000元的订单
high_value_orders = list(filter(lambda order:
order["amount"] > 1000, orders))
# 2. 计算每个订单的折扣金额(折扣率为10%)
discounted_orders = list(map(lambda order: {**order,
"discount": order["amount"] * 0.1}, orders))
# 3. 计算所有订单的总金额
amounts = list(map(lambda order: order["amount"], orders))
total_amount = reduce(lambda x, y: x + y, amounts)
# 4. 找出订单金额最高的订单
highest_amount_order = max(orders, key=lambda order:
order["amount"])
# 输出结果
print("订单金额大于1000元的订单:", high_value_orders)
print("每个订单的折扣金额:", discounted_orders)
print("所有订单的总金额:", total_amount)
print("订单金额最高的订单:", highest_amount_order)

六、递归函数的引入

如果一个函数在执行过程中调用自身,那么这个函数就可以称为递归函数。 也就是在函数体中调用自己。
递归函数的特点:
1 、函数体中调用自己
2 、有一个条件作为出口。不然一直自己调用自己层层套下去就成死循环 了,所以必须要有个条件终止。

阶乘案例:、

def fbnq(n):
    if n == 1:
        return 1
    else:
        return n * fbnq(n-1)
print(fbnq(4))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2277176.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python-leetcode-矩阵置零

73. 矩阵置零 - 力扣(LeetCode) class Solution:def setZeroes(self, matrix: List[List[int]]) -> None:"""Do not return anything, modify matrix in-place instead."""m, n len(matrix), len(matrix[0])row_zero …

MySQL数据库(SQL分类)

SQL分类 分类全称解释DDLData Definition Language数据定义语言,用来定义数据库对象(数据库,表,字段)DMLData Manipulation Language数据操作语言,用来对数据库表中的数据进行增删改DQLData Query Languag…

计算机网络 笔记 网络层1

网络层功能概述 主要的任务是把分组从源端传输到目的端,为分组交换网上的不同主句提供通信服务,网络层的传输单位是数据报。 主要的功能; 1,路由选择:路由选择指网络层根据特定算法,为数据包从源节点到目…

MyBatis-什么是MyBatis?以及MyBatis的快速入门。

简介 什么是 MyBatis? 什么是MyBatis? MyBatis是一款优秀的 持久层 框架,用于简化JDBC的开发。(框架:是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。在框架的基础上进行软件开发更加高效、规范、通用、…

Linux Kernel 之十 详解 PREEMPT_RT、Xenomai 的架构、源码、构建及使用

概述 现在的 RTOS 基本可以分为 Linux 阵营和非 Linux 阵营这两大阵营。非 Linux 阵营的各大 RTOS 都是独立发展,使用上也相对独立;而 Linux 阵营则有多种不同的实现方法来改造 Linux 以实现实时性要求。本文我们重点关注 Linux 阵营的实时内核实现方法! 本文我们重点关注 …

Swift 趣味开发:查找拼音首字母全部相同的 4 字成语(上)

概述 Swift 语言是一门现代化、安全、强大且还算性感的语言。在去年 WWDC 24 中苹果正式推出了秃头码农们期待许久的 Swift 6.0,它进一步完善了 Swift 语言的语法和语义,并再接再厉——强化了现代化并发模型的安全性和灵活性。 这里我们不妨用 Swift 来…

docker一张图理解

1、push 将本地的镜像上传到镜像仓库,要先登陆到镜像仓库。参数说明: –disable-content-trust : 忽略镜像的校验,默认开启 # 上传本地镜像myapache:v1到镜像仓库中。 docker push myapache:v1 1.2、search 从Docker Hub查找镜像。参数说明: –…

IoTDB 常见问题 QA 第三期

关于 IoTDB 的 Q & A IoTDB Q&A 第三期持续更新!我们将定期汇总我们将定期汇总社区讨论频繁的问题,并展开进行详细回答,通过积累常见问题“小百科”,方便大家使用 IoTDB。 Q1:查询最新值 & null 数据相加方…

MyBatis实现数据库的CRUD

本文主要讲解使用MyBatis框架快速实现数据库中最常用的操作——CRUD。本文讲解的SQL语句都是MyBatis基于注解的方式定义的,相对简单。 Mybatis中#占位符和$拼接符的区别 “#”占位符 在使用MyBatis操作数据库的时候,可以直接使用如下SQL语句删除一条数…

Spring Boot 下的Swagger 3.0 与 Swagger 2.0 的详细对比

先说结论: Swgger 3.0 与Swagger 2.0 区别很大,Swagger3.0用了最新的注释实现更强大的功能,同时使得代码更优雅。 就个人而言,如果新项目推荐使用Swgger 3.0,对于工具而言新的一定比旧的好;对接于旧项目原…

关于2025年智能化招聘管理系统平台发展趋势

2025年,招聘管理领域正站在变革的十字路口,全新的技术浪潮与不断变化的职场生态相互碰撞,促使招聘管理系统成为重塑企业人才战略的关键力量。智能化招聘管理系统平台在这一背景下迅速崛起,其发展趋势不仅影响企业的招聘效率与质量…

go语言的sdk 适合用go原生还是gozero框架开发的判断与总结

在决定是否使用 Go 原生(纯 Go)开发,还是使用 GoZero 框架开发时,主要取决于项目的需求、规模和开发的复杂性。GoZero 框架提供了一些额外的功能,如微服务架构、RPC 支持、API 网关、任务调度等,这些是基于…

Elasticsearch 批量导入数据(_bluk方法)

官方API&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html 建议先看API POST /<索引名>/_bulk 格式要求&#xff1a; POST _bulk { "index" : { "_index" : "test", "_id" : &q…

Mysql--重点篇--索引(索引分类,Hash和B-tree索引,聚簇和非聚簇索引,回表查询,覆盖索引,索引工作原理,索引失效,索引创建原则等)

索引是数据库中用于加速查询操作的重要机制。通过索引&#xff0c;MySQL可以快速定位到满足查询条件的数据行&#xff0c;而不需要扫描整个表。合理的索引设计可以显著提高查询性能&#xff0c;但不合理的索引可能会导致性能下降和磁盘空间浪费。因此&#xff0c;理解索引的工作…

mybatis-spring @MapperScan走读分析

接上一篇文章&#xff1a;https://blog.csdn.net/qq_26437925/article/details/145100531&#xff0c; 本文注解分析mybatis-spring中的MapperScan注解&#xff0c;则将容易许多。 目录 MapperScan注解定义ConfigurationClassPostProcessor扫描注册beanDefinitionorg.mybatis.s…

【STM32】HAL库USB实现软件升级DFU的功能操作及配置

【STM32】HAL库USB实现软件升级DFU的功能操作及配置 文章目录 DFUHAL库的DFU配置修改代码添加条件判断和跳转代码段DFU烧录附录&#xff1a;Cortex-M架构的SysTick系统定时器精准延时和MCU位带操作SysTick系统定时器精准延时延时函数阻塞延时非阻塞延时 位带操作位带代码位带宏…

计算机视觉算法实战——实时车辆检测和分类(主页有相关源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ ​​​​​​​​​​​​​​​​​​ 1. 领域介绍✨✨ 实时车辆检测和分类是计算机视觉中的一个重要应用领域&#xff0c;旨在从视频流或…

机器学习(1):线性回归概念

1 线性回归基础 1.1 什么是线性 例如&#xff1a;汽车每小时60KM&#xff0c;3小时可以行使多长距离&#xff1f;已知汽车的速度&#xff0c;则汽车的行使距离只与时间唯一相关。在二元的直角坐标系中&#xff0c;描出这一关系的图是一条直线&#xff0c;所以称为线性关系。 线…

ThinkPHP 8的一对一关联

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用VS Code开发ThinkPHP项目-CSDN博客 编程与应用开…

探索图像编辑的无限可能——Adobe Photoshop全解析

文章目录 前言一、PS的历史二、PS的应用场景三、PS的功能及工具用法四、图层的概念五、调整与滤镜六、创建蒙版七、绘制形状与路径八、实战练习结语 前言 在当今数字化的世界里&#xff0c;视觉内容无处不在&#xff0c;而创建和编辑这些内容的能力已经成为许多行业的核心技能…