当前位置: 首页 > article >正文

Python入门10:高阶函数

一、什么是高阶函数

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.kler.cn/a/503231.html

相关文章:

  • 【Rust】引用与借用
  • 计算机网络 (36)TCP可靠传输的实现
  • 计算机网络 | 什么是公网、私网、NAT?
  • 基于深度学习算法的AI图像视觉检测
  • 如何用SQL语句来查询表或索引的行存/列存存储方式|OceanBase 用户问题集锦
  • 微信小程序实现长按录音,点击播放等功能,CSS实现语音录制动画效果
  • MERN全栈脚手架(MongoDB、Express、React、Node)与Yeoman详解
  • 力扣152. 乘积最大子数组
  • pytorch nn.Dropout类介绍
  • 04.计算机体系三层结构与优化(操作系统、计算机网络、)
  • Vue JavaScript 小写数字金额转换成大写汉字(附编程思路)
  • 简识MySQL的InnoDB Locking锁的分类
  • ue5 设置角色属性(生命值,蓝条值,能量值)c++
  • 基于WebRTC实现音视频通话
  • day01-HTML-CSS——基础标签样式表格标签表单标签
  • 斯坦福大学李飞飞教授团队ARCap: 利用增强现实反馈收集高质量的人类示教以用于机器人学习
  • 安装软件缺少msvcp110.dll怎么办?出现dll丢失的解决方法
  • LeetCode热题100(哈希篇)
  • unity学习18:unity里的 Debug.Log相关
  • 如何使用 Excel 进行多元回归分析?
  • 【数据结构】C语言顺序栈和链式栈的使用
  • 科技快讯 | 华为余承东2025新年信;教育部拟同意设置福耀科技大学等本科院校;我国成功发射一箭10星
  • <C++学习> C++ Boost 字符串操作教程
  • Day31补代码随想录20250110贪心算法5 56.合并区间|738.单调递增的数字|968.监控二叉树(可跳过)
  • LoRaWAN节点学习笔记
  • ASP.NET Core - 日志记录系统(一)