python基础day-11:高阶函数

本文深入探讨Python的高阶函数,解释函数作为变量的概念,包括赋值、修改、作为序列元素、参数及返回值。介绍了实参高阶函数如max、min、sorted、map和reduce的使用,并探讨了无参装饰器的定义和应用,展示了如何通过装饰器为函数添加新功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

高阶函数

一、函数就是变量

  • python中定义函数就是定义类型是function的变量
  • 函数名就是变量名
a = 10
b = lambda x: x*3
c = {'i': 1, 'j': 2}
print(type(a), type(b), type(c))  # <class 'int'> <class 'function'> <class 'dict'>

1.1 一个变量可以给另一个变量赋值

  • 加()是调用,不加()是变量名
def func1():
    print('我是一个函数。')


z = func1
z()  # 我是一个函数。

1.2 修改变量的值

  • 变量可以重新赋值
func1 = 100
print(func1)  # 100

1.3 变量作为序列的元素

def func2():
    return '嘿嘿'


list1 = [func1, func2, func2()]
print(list1[0])  # 100
print(list1[1])  # <function func2 at 0x00000287C9D6A318>
print(list1[2])  # 嘿嘿

1.4 变量作为函数的参数

  • 实参高阶函数
def func3(f):
    return f , '什么'


print(func3(func2))
print(func3(func2()))

1.5 变量作为函数的返回值

  • 返回值高阶函数
  • 一个函数的返回值是个函数
def func4():
    def g():
        print('我是小函数')
    return g


func4()()  # 我是小函数 - 相当于调用g()
# 面试题
# 定义函数时不执行函数体,所以i 保持原样
# for 循环中的i 在函数外,是全局变量,循环结束时,i 值为4
list2 = []
for i in range(5):
    list2.append(lambda x: x*i)

print(list2[1](2))  # 8
print(list2[2](2))  # 8

二、实参高阶函数

2.1 定义

  • 参数是函数的函数就是实参高阶函数
def func1(x):
    return x()


def func2():
    print('helloo')


func1(func2)  # func1 就是实参高阶函数

2.2 系统常见实参高阶函数

  • max
  • min
  • sorted
  • map
  • reduce
2.2.1 max、min
  • max(序列) - 比较元素的大小来获取值最大的元素
  • max(序列, key=函数) - 函数决定求最大值时候的比较对象
    1. 是个函数
    2. 这个函数有且只有一个参数(这个参数指向序列中的元素)
    3. 有一个返回值(比较对象)
nums1 = [23, 23, 345, 456, 2, 34, 7, 8, 786, 56, 345]

students = [
    {'name': '小明', 'age': 23, 'score': 89},
    {'name': '小红', 'age': 20, 'score': 96},
    {'name': '小张', 'age': 21, 'score': 90}
]

# 列表中最大的元素
print(max(nums1))      # 768
# 分数最高的学生
# print(max(students))  # TypeError: '>' not supported between instances of 'dict' and 'dict'

# 求列表中个位数最大的元素
print(max(nums1, key=lambda x: x % 10))  # 8
# 分数最高的学生
print(max(students, key=lambda x: x['score']))  # {'name': '小红', 'age': 20, 'score': 96}
# 年龄最小的学生
print(min(students, key=lambda x: x['age']))  # {'name': '小红', 'age': 20, 'score': 96}
# 练习:
# 取各位之和最大的元素
nums2 = [23, 78, 90, 73, 233, 91]
print(max(nums2, key=lambda x: sum([int(n) for n in str(x)])))
2.2.2 sorted
  • sorted(序列) - 比较序列中元素的大小对序列中的元素从小到大排序
  • sorted(序列,key=函数) - 函数决定排序的比较方法
    1. 函数
    2. 一个参数,指向序列的元素
    3. 一个返回值,即为比较对象
print(nums2)          # [23, 78, 90, 73, 233, 91]
print(sorted(nums2))  # [23, 73, 78, 90, 91, 233]

# 按个位数从小排
print(sorted(nums2, key=lambda x: x % 10))  # [90, 91, 23, 73, 233, 78]

# 按学生年龄从小排
students = [
    {'name': '小明', 'age': 23, 'score': 89},
    {'name': '小红', 'age': 20, 'score': 96},
    {'name': '小张', 'age': 21, 'score': 90}
]
print(sorted(students, key=lambda x: x['age']))
'''
[{'name': '小红', 'age': 20, 'score': 96},
 {'name': '小张', 'age': 21, 'score': 90},
 {'name': '小明', 'age': 23, 'score': 89}]

'''
2.2.3 map
  • map(函数,序列) - 将序列按指定方式进行转换
  • 原序列 -> 新序列
    1. 有一个参数,指向序列中的元素
    2. 一个返回值,作为新序列中元素
nums2 = [23, 78, 90, 73, 233, 91]
print(list(map(lambda x: x*2, nums2)))  # [46, 156, 180, 146, 466, 182]
  • map跟推导式有什么区别?由于可以自定义函数来用,所以比列表推导式灵活,推导式只能一条语句

  • 原序列可以有多个

  • map(函数,序列1,序列2)

    1. 两个参数,分别指向两个序列中的元素,元素个数一致
    2. 一个返回值,是新序列中的元素
names = ['张三', '李四', '小明', '小红']
ages = [13, 14, 16, 14]
print(list
      (map(lambda x1, x2:
           {'name': x1, 'age': x2},
           names, ages)))
'''
[{'name': '张三', 'age': 13},
 {'name': '李四', 'age': 14},
 {'name': '小明', 'age': 16},
 {'name': '小红', 'age': 14}]
'''

# 班级总成绩
chinese = [90, 89, 88, 99, 27, 76, 56]
english = [98, 78, 66, 82, 90, 12, 78]
math = [23, 98, 100, 72, 69, 27, 96]
stu_totall = map(lambda c, e, m: c+e+m, chinese, english, math)
print(list(stu_totall))  # [211, 265, 254, 253, 186, 115, 230]
2.2.4 reduce
from functools import reduce
  • reduce(函数,序列,初始值)
    1. 两个参数

      • 第一个 - 第一次指向初始值;第二次开始指向上一次的运算结果
        如果没有初始值,第一个默认是序列的第一个元素
      • 第二个 - 指向序列中的每个元素
    2. 一个返回值,决定运算规则

nums2 = [23, 78, 90, 73, 233, 91]
print(reduce(lambda x, item: x+item, nums2, 0))  # 588
  • 函数会被不断调用
# 将数字拼接在一起
print(reduce(lambda heap, item: heap+str(item), nums2, ''))  # 2378907323391

三、无参装饰器

3.1 什么是装饰器

  • 作用:用来给函数添加功能
  • 本质:也是个函数;实参高阶函数+返回值高阶函数+糖语法
  • 用法:输入原函数,输出改造后的新函数
    def 函数名1(参数1):
            def 函数名2(*args, **kwargs):
                新增功能的代码
                原函数的返回值 = 调用原函数的代码 参数1(*args, **kwargs)
                return 原函数的返回值
           return 函数名2
import time


def count_time(fn):
    def new_fn(*args, **kwargs):
        start = time.time()
        result = fn(*args, **kwargs)
        end = time.time()
        print(end - start)
        return result
    return new_fn

3.2 使用装饰器

  • 在被装饰的函数定义上一行加上 @装饰器名

@count_time
def func1():
    print('函数1的功能')


@count_time
def func2(x, y):
    print(x+y)


func1()
func2(1, 2)
# 练习:用装饰器,在函数开始打印‘start!‘,
def report_start(fn):
    def new_fn(*args, **kwargs):
        print('start!')
        result = fn(*args, **kwargs)
        return result
    return new_fn


@report_start
def say_hello():
    print('hello world!')


say_hello()
  • 糖语法本质
    fn = 装饰器(fn)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值