Python课堂笔记-第十讲(函数)

本文深入讲解Python中的高阶函数,包括map、reduce、filter和sorted的使用,介绍匿名函数、闭包和装饰器的概念及应用,是Python学习者提升技能的必备教程。

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

一、高阶函数

1. 高阶函数的2个特点

高阶函数的形式可以有两种:

  • 把一个函数名当作实参传给另外一个函数(“实参高阶函数”)
  • 返回值中包含函数名(“返回值高阶函数”)

符合任意的一个特点,这个函数就是个高阶函数。
当我们使用一个函数名作为参数,实际上是指将指定的代码传递进了目标函数。

# 1 接收一个或多个函数作为参数
# 2 将函数作为返回值返回的也是个高阶函数

# 当我们使用一个函数作为参数的时候,实际上是将指定的代码传递到了目标函数
lst = [1,2,3,4,5,6,7,8,9,10]
a = 1

# 在函数内部定义一个函数 用来检测一个任意的偶数
def fn2(i):
    if i % 2 == 0:
        return True

def fn3(i):
    if i > 5:
        return True
    return False

def fn4(i):
    if i % 3 == 0:
        return True
    return False
    
# 定义一个函数
# 可以指定一个列表中的所有的偶数,保存到一个新的列表
def fn(func,l):

    # 参数 l 就是被指定的列表 func
    # 创建一个新的列表
    new_lst = []

    for n in l:
        # 判断n的奇偶
        if func(n):
            new_lst.append(n)

    return new_lst

print(fn(fn2,lst)) # 求偶数

print(fn(fn4,lst)) # 求3的倍数

# 运行结果
[2, 4, 6, 8, 10]
[3, 6, 9]

2. 常用的内置高阶函数

map()函数

map函数接收两个参数,一个是函数,一个是序列;
map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。

格式:map(func, iter)

def func(x):
    return x * x

print map(func,[1,2,3,4,5]) 

# 输出结果
[1,4,9,16,25]

reduce()函数

reduce把一个函数作用在一个序列上;
reduce必须接收两个参数,把结果继续和序列的下一个元素做计算。

格式:reduce(func, iter)

from functools import reduce

lt = [1, 2, 3, 4, 5]

# 求和
# s = reduce(lambda x,y: x+y, lt)
# 转换为12345
s = reduce(lambda x,y: x*10+y, lt)

print(s)

# 输出结果
12345

filter()函数

filter把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

格式:filter(func, iter)

lt = [1, 2, 3, 4, 5]

# 提取偶数
f = filter(lambda x: x%2==0, lt)

print(list(f))

# 输出结果
2,4

sorted()函数

sorted排序后返回一个新的列表,并不改变原有变量

格式:sorted(iterable[, cmp[, key[, reverse]]])

  • iterable:可迭代对象
  • cmp :比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出, 此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。
  • key :主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
  • reverse:排序规则,reverse = True 降序 , reverse = False 升序(默认)。
# 列表排序
s1 = sorted([1,2,4,1,2,3,4,5,3,2])
print(s1)

# 指定使用排序元素的函数
d = {"a":1,"b":3,"c":2}
s2 = sorted(d.items(),key=lambda item:item[1]) 
print(s2)

输出结果:
[1, 1, 2, 2, 2, 3, 3, 4, 4, 5]
[('a', 1), ('c', 2), ('b', 3)]

sort 与 sorted 区别:
sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作;
sort 方法返回的是对已经存在的列表进行操作,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。


二、匿名函数

匿名函数最大的好处就是,它只会用一次,用完只会就会从内存消失。

语法:lambda 参数列表 : 返回值

# 定义并调用一个匿名函数,该函数将对参数进行+1并将结果返回
result = (lambda x: x + 1)
print(result)

# 当然匿名函数也可以传递多个参数
result = (lambda x, y: x + y)
print(result)

# 不止可以对数值变量进行计算,还可以对列表进行处理,下面的代码意思相当于result = [1,2,3,4,5] * 2
result = (lambda x: x * 2)
print(result)

lambda函数表达式是专门用来创建一些简单的函数,它也是函数的另一种创建方式。

# filter() 就是一个高阶函数 它需要将别的函数作为参数来传递
# 可以将我们的可迭代对象进行一个过滤
# 返回值 可迭代的对象

# 匿名函数最大的好处就是 它只会用一次,用完只会就会从内存消失
lst = [1,2,3,4,5,6,7,8,9,10]

def fn4(i):
    if i % 3 == 0:
        return True
    return False
# filter(fn4,lst) 等价于 filter(lambda i : i % 3 == 0,lst)
r = filter(lambda i : i % 2 != 0,lst)
print(r)
print(list(r))

# 输出结果
[1, 3, 5, 7, 9]

三、闭包

第二种形式的高阶函数,将函数作为参数返回,这种高阶函数我们称之为闭包。

闭包的好处:

  • 通过闭包可以创建⼀些只有当前函数能访问的变量;
  • 可以将一些私有数据藏到闭包中。
def fn():
    a = 10
    # 在函数内部在定义一个函数
    def fn2():
        print('我是fn2',a)
    # 将内部函数fn2作为返回值返回
    return fn2
r = fn()
r()
print(fn())

# 输出结果
我是fn2 10
<function fn.<locals>.fn2 at 0x0000017A87F8A950>

形成闭包的条件:

  • 函数嵌套;
  • 将内部函数作为返回值返回;
  • 内部函数必须要使用到外部函数的变量。
# inner作为一个函数被outer返回,保存在一个变量foo,并且我们能够对它进行调用foo()
def outer():
    x = 1
    def inner():
        print x # 1
     return inner
foo = outer()
foo()
# 运行结果
1

从这个例子中你能够看到闭包:

  • 被函数记住的封闭作用域
  • 能够被用来创建自定义的函数
def outer(x):

    def inner():
        print(x) # 1
    return inner

print1 = outer(1)
print2 = outer(2)

print1()
print2()

# 输出结果
1
2

四、装饰器

1. 装饰器的引⼊

我们可以直接通过修改函数中的代码来完成需求,但是会产生以下一些问题:

  • 如果修改的函数多,修改起来会比较麻烦,不方便后期的维护;
  • 这样做会违反开闭原则(ocp);
  • 程序的设计,要求开放对程序的扩展,要关闭对程序的修改。

2. 装饰器的使⽤

装饰器其实就是一个闭包,把一个函数当做参数然后返回一个替代版函数。

def outer(some_func):

    def inner():
        print("before some_func")
        ret = some_func()  # 1
        return ret + 1

    return inner

def foo():
    return 1

decorated = outer(foo)  # 2
r = decorated()
print(r)

# 输出结果
before some_func
2

通过装饰器可以在不修改原来的函数的情况下对函数进行扩展,在开发中,我们都是通过装饰器来扩展函数的功能的。

# 定义一个函数 就是对其他函数进行扩展的 扩展的功能一个 是打印函数开始执行 一个是打印函数执行结束
def start_end(old):

    # 内部创建了一个函数
    def new_function(*args,**kwargs):
        print('函数开始执行')
        r = old(*args,**kwargs)
        print('函数执行结束')
        # 返回函数的执行结果
        return r
    # 返回新的函数
    return new_function

# 像类似于start_end(old)这种函数我们就称之为装饰器
# 通过装饰器可以在不修改原来的函数的情况下对函数进行扩展
# 在开发中,我们都是通过装饰器来扩展函数的功能的
@start_end
def speak():
    print('同学们辛苦了!!!!')

speak()

# 输出结果
函数开始执行
同学们辛苦了!!!!
函数执行结束

装饰器的原则组成:< 函数+实参高阶函数+返回值高阶函数+嵌套函数+语法糖 = 装饰器 >
参考链接:Python装饰器的通俗理解


总结

python核心编程课堂笔记-第十讲(函数)点击访问源图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值