python中的高阶函数讲解

函数的说明

# 函数式编程
#  - 在Python中,函数是一等对象
#       - 一等对象一般都会具有如下特点:
#       ① 对象是在运行时创建的
#       ② 能赋值给变量或作为数据结构中的元素
#       ③ 能作为参数传递
#       ④ 能作为返回值返回

#  - 高阶函数
#      - 高阶函数至少要符合以下两个特点中的一个
#        ① 接收一个或多个函数作为参数
#        ② 将函数作为返回值返回
#       当我们使用一个函数作为参数时,实际上是将指定的代码传递进了目标函数

将函数作为参数的高阶函数

# 定义一个函数,用来检查一个任意数的数字是否是偶数
def fn2(i):
    return i % 2 == 0


# 定义一个函数,用来检查指定的一个任意的数字是否大于5
def fn3(i):
    return i > 5


# 定义一个函数,根据传入的指定功能的函数,将指定列表中满足函数要求的数字,保存到一个新列表中返回
def fn(func, list):
    '''
    根据传入的指定功能的函数,将指定列表中满足函数要求的数字,保存到一个新列表中返回
    :param func:
    :param list:
    :return: new_list
    '''
    # 创建一个新列表
    new_list = []
    for i in list:
        if func(i):
            new_list.append(i)
    return new_list


# 调用函数
lst = [1, 2, 3, 4, 5, 6, 7, 9]
# 打印返回结果,根据传入不同的函数作为参数,来实现不同的功能。
print(fn(fn2, lst))
print(fn(fn3, lst))

匿名函数

filter()函数

filter()函数可以把函数作为其参数,其也是一个内置的高阶函数。

# filter()
# filter()可以从序列中过滤出符合条件的元素,保存到一个新的序列中
# 参数:
#   1.函数,根据该函数来过滤序列(可迭代的结构)
#   2.需要过滤的序列(可迭代的结构)
# 返回值:
#   过滤后的新序列(可迭代的结构)
# 判断一个数是否为奇数

代码演示:

# 判断一个数是否为奇数
def fn4(i):
    return i % 2 != 0


lst = [1, 2, 3, 4, 5, 6, 7, 9]
print(filter(fn4, lst))  # 打印的是filter对象
print(list(filter(fn4, lst)))  # 需要再转为list,才能打印出具体值

引入lambda函数

# 上面的fn4是作为参数传递进filter()函数中
#   而fn4实际上只有一个作用,就是作为filter()的参数
#   filter()调用完毕以后,就是作为filter()的参数
# 匿名函数 lambda 函数表达式 (语法糖)
# lambda函数表达式专门用来创建一些简单的函数,他是函数创建的又一种方式
# 语法: lambda 参数列表 : 返回值
# 匿名函数一般都是作为参数使用,其他地方一般不会使用,匿名函数都是比较简单的代码,过于复杂的业务逻辑不能使用匿名函数
def fn5(a, b):
    return a + b


# 使用lambda表达式函数,实现fn5函数的相同功能
# r = (lambda a,b:a+b)(10,20) #一般不这样使用
# print("r=", r)
# 也可以将匿名函数赋值给一个变量,一般不会这么做
# fn6 = lambda a, b: a + b
# print(fn6(10, 20))

# 一般这样用,使用lambda匿名函数实现上述fn4函数的功能
r = filter(lambda i: i % 2 != 0, lst)
print("r=", list(r))

map()函数

# map()函数可以对可迭代对象中的所有元素做指定的操作,然后将其添加到一个新的对象中返回
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

r = map(lambda i: i ** 2, l)
print(r)  # <map object at 0x00000174220FB250>
print(list(r))  # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

sort()函数

# 该方法用来对列表中的元素进行排序
# sort()方法默认是直接比较列表中的元素的大小
# 在sort()中可以接收一个关键字参数,key
#   key需要一个函数作为参数,当设置了函数作为参数
#   每次都会以列表中的一个元素作为参数来调用函数,并且使用函数的返回值来比较元素的大小
l = ['bb', 'aaaa', 'c', 'dddddddd', 'kkkkkkk']
l.sort()  # 默认是升序
l.sort(reverse=True)  # 通过位置参数,指定reverse为True实现倒序排序
print(l)
l.sort(key=len)  # 根据元素的长度进行排序
print(l)
l = [2, 5, '1', 3, '6', '4']
# l.sort()  # 因l列表中既有数值又有字符串,彼此之间不能进行比较,会报错
# l.sort(key=int)  # 将l中的元素都用int函数转化后再进行比较,注意并改变原列表中的数据类型
l.sort(key=str)  # 将l中的元素都用str函数转化后再进行比较,注意并改变原列表中的数据类型
print(l)

sorted()函数

# 这个函数和sort()的用法基本一致,但是sorted()可以对任意的序列进行排序
#  并且使用sorted()排序不会影响原来的对象,而是返回一个新对象
l = [2, 5, '1', 3, '6', '4']
print('排序前:',l)
print(sorted(l,key=int))
print('排序后:',l)

上面介绍的filter、map、sort、sorted 都属于Python内置的高阶函数

将函数作为返回值的高阶函数

# 将函数作为返回值返回,也是一种高阶函数
# 这种高阶函数我们也称为叫做闭包,通过闭包可以创建一些只有当前函数访问的变量
#   可以将一些私有的数据藏到闭包中
def fn():
    a = 10

    # 函数内部再定义一个函数
    def inner():
        print('我是fn2', a)

    # 将内部函数 inner作为返回值返回
    return inner


# r是一个函数,是调用fn()后返回的函数
# 这个函数是在fn()内部定义,并不是全局函数
# 所以这个函数总是能访问到fn()函数内的变量
r = fn()
r()

闭包

# 形成闭包的要件
#   ① 函数嵌套
#   ② 将内部函数作为返回值返回
#   ③ 内部函数必须要使用到外部函数的变量
# 另外一个求平均值的例子
def make_averager():
    # 创建一个列表,用来保存数值
    nums = []

    # 创建一个函数,用来计算平均值
    def averager(n):
        # 将n添加到列表中
        nums.append(n)
        # 求nums中已有元素的平均值
        return sum(nums) / len(nums)

    return averager  # 将内部函数作为返回值返回,每次返回的这个函数都是一个新函数

averager = make_averager()
print(averager(10))
print(averager(20))
nums = []  # 这里的nums和函数内部的nums不是同一个变量,不会影响到内部的nums
print(averager(30))
print(averager(40))

猜你喜欢

转载自blog.csdn.net/adminstate/article/details/131142800