Python入门10:高阶函数

一、什么是高阶函数

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

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

1.2、高阶函数的特点:

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

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

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

案例:

# 需求:定义一个函数,带两个整数类型的参数
# 该函数的功能是把两个 参数整理之后 做求和计算,并把结果返回
非高阶函数的写法:
def my_function(num1,num2):# 对传入的两个参数进行平方处理new_num1 = num1**2new_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 = 0for i in args:sum += iprint("我是内部函数里面的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 1else:return n * fbnq(n-1)
print(fbnq(4))

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

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

相关文章

浅谈云计算12 | KVM虚拟化技术

KVM虚拟化技术 一、KVM虚拟化技术基础1.1 KVM虚拟化技术简介1.2 KVM虚拟化技术架构1.2.1 KVM内核模块1.2.2 用户空间工具(QEMU、Libvirt等) 二、KVM虚拟化技术原理2.1 硬件辅助虚拟化2.2 VMCS结构与工作机制 三、KVM虚拟化技术面临的挑战与应对策略3.1 性…

GO:GO程序如何处理缓存加载和大数据缓存

如果我们会在程序启动时,需要加载所有数据,最简单的方式就是程序启动,通过轮训从数据库拉取所有数据,并写入到本地缓存中。 问题:数据量较大的时候,程序加载慢,启动时间长,遇到问题不…

【优选算法篇】:分而治之--揭秘分治算法的魅力与实战应用

✨感谢您阅读本篇文章,文章内容是个人学习笔记的整理,如果哪里有误的话还请您指正噢✨ ✨ 个人主页:余辉zmh–CSDN博客 ✨ 文章所属专栏:优选算法篇–CSDN博客 文章目录 一.什么是分治算法1.分治算法的基本概念2.分治算法的三个步…

OpenAI Whisper:语音识别技术的革新者—深入架构与参数

当下语音识别技术正以前所未有的速度发展,极大地推动了人机交互的便利性和效率。OpenAI的Whisper系统无疑是这一领域的佼佼者,它凭借其卓越的性能、广泛的适用性和创新的技术架构,正在重新定义语音转文本技术的规则。今天我们一起了解一下Whi…

python+playwright自动化测试(一):安装及简单使用,截图录屏

目录 基本使用 浏览器调用 启用浏览器 创建窗口对象 访问URL 页面的刷新、返回、前进 关闭 截图、录屏、保存pdf 截图 录屏 保存为pdf 设置窗口大小 调试模式 手机模式及new_context的更多参数 手机模式 new_context的其他参数 设置语言和时区 设置和修改位置…

初识C++(二)

六、引用 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。 通俗地讲,可以理解为一个人能够拥有多个称呼,这些所有的称呼都是表示这一…

【RedisStack】Linux安装指南

【RedisStack】Linux安装指南.md 前言下载解压创建启动文件设置密码把密码设置到环境变量启动/停止相关命令测试&验证官网资料参考资料 前言 Redis Stack是使用Redis的最佳起点。我们将我们必须提供的最好的技术捆绑在一起,形成一个易于使用的软件包。Redis St…

达梦8-DMSQL程序设计学习笔记1-DMSQL程序简介

1、DMSQL程序简介 DMSQL程序是达梦数据库对标准SQL语言的扩展,是一种过程化SQL语言。在DMSQL程序中,包括一整套数据类型、条件结构、循环结构和异常处理结构等,DMSQL程序中可以执行SQL语句,SQL语句中也可以使用DMSQL函数。 DMSQ…

STM32 FreeRTOS 基础知识

多任务处理 内核是操作系统的核心组件。诸如 Linux 这样的操作系统采用的内核, 看似允许用户同时访问计算机。很明显,多个用户可以同时执行多个程序。 每个执行程序都是受操作系统控制的任务(或线程)。如果一个操作系统能够以这…

T-SQL编程

目录 1、T-SQL的元素 1.1 标识符 1. 常规标识符 2. 分隔标识符 1.2 变量 1. 全局变量 2. 局部变量 1.3 运算符 1. 算数运算符 2. 赋值运算符 3. 位运算符 4. 比较运算符 5. 逻辑运算符 6. 字符串连接运算符 7. 一元运算符 8. 运算符的优先级和结合性 1.4 批处…

js中的Object.defineProperty()详解

文章目录 一、Object.defineProperty()二、descriptor属性描述符2.1、数据描述符2.2、访问器描述符2.3、descriptor属性2.3.1、value2.3.2、writable2.3.3、enumerable (可遍历性)2.3.4、configurable (可配置性) 三、注意事项 一…

【搭建JavaEE】(2)Tomcat安装配置和第一个JavaEE程序

Tomcat–容器(Container) 下载 Apache Tomcat - Welcome! 下载完成 请求/响应 结构 测试 查看Jdk版本 改端口号localhost8080–>8099 学学人家以后牛逼了可以用自己名字当文件夹名 配置端口8099 找到server文件 用记事本打开 再打开另一个logging文件 ”乱码解决“步骤&…

centos7.6 安装nginx 1.21.3与配置ssl

1 安装依赖 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel2 下载Nginx wget http://nginx.org/download/nginx-1.21.3.tar.gz3 安装目录 mkdir -p /data/apps/nginx4 安装 4.1 创建用户 创建用户nginx使用的nginx用户。 #添加www组 # groupa…

高级软件工程-复习

高级软件工程复习 坐标国科大,下面是老师说的考试重点。 Ruby编程语言的一些特征需要了解要能读得懂Ruby程序Git的基本命令操作知道Rails的MVC工作机理需要清楚,Model, Controller, View各司什么职责明白BDD的User Story需要会写,SMART要求能…

TrollFools 2.10-22 插件注入工具 官方版

《TrollFools巨魔设备专用插件注入工具》这是一款专为巨魔设备打造的插件注入神器,功能强大且操作便捷。它能够轻松地将插件注入通过AppStore商店下载的任意APP中,同时也能随时卸载,丝毫不影响APP的正常使用。注入后的APP仍可正常更新&#x…

30分钟内搭建一个全能轻量级springboot 3.4 + 脚手架 <1> 5分钟快速创建一个springboot web项目

快速导航 <1> 5分钟快速创建一个springboot web项目 <2> 5分钟集成好最新版本的开源swagger ui&#xff0c;并使用ui操作调用接口 <3> 5分钟集成好druid并使用druid自带监控工具监控sql请求 <4> 5分钟集成好mybatisplus并使用mybatisplus generator自…

arcgis中生成格网矢量带高度

效果 1、数据准备 (1)矢量边界(miain.shp) (2)DEM(用于提取格网标高) (3)DSM(用于提取格网最高点) 2、根据矢量范围生成格网 模板范围选择矢量边界,像元宽度和高度根据坐标系来输入,我这边是4326的,所以输入的是弧度,输出格网矢量gewang.shp 3、分区统计 …

海豚调度DolphinScheduler-3.1.9配置windows本地开发环境

源代码下载地址https://dolphinscheduler.apache.org/zh-cn/docs/3.1.9 1.Zookeeper安装与使用 如图下载解压zookeeper安装包&#xff0c;并创建data和log目录 下载地址 https://archive.apache.org/dist/zookeeper/zookeeper-3.6.4/apache-zookeeper-3.6.4-bin.tar.gz 进入…

P1图文解析:初识算法和数据结构

文章目录 前言1、算法例子1.1、查字典&#xff08;二分查找算法&#xff09;1.2、整理扑克&#xff08;插入排序算法&#xff09;1.3、货币找零&#xff08;贪心算法&#xff09; 2、算法与数据结构2.1、算法定义2.2、数据结构定义2.3、数据结构与算法的关系2.4、独立于编程语言…

校园跑腿小程序---轮播图,导航栏开发

hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生…