Python进阶到高级:高阶函数

2023年 8月 18日 102.5k 0

高阶函数是通过组合简单函数成一个复杂表达式的函数。你可以理解成,函数套函数。函数式编程是一种编程范式,这部分内容可以体现 Python 在函数式编程上的应用。

1、lambda

匿名函数(lambda),这个函数没有函数名,用于一行创建一个函数,并返回一个函数对象,也是一种语法糖。

定义一个匿名函数,功能就是参数加1:

my_lb = lambda x: x + 1

普通函数的写法就是:

def add_one(n):
    return n + 1

你看,确实很简洁哈,my_lb 不是函数名哈,有函数名它就不是匿名函数了,而是函数对象,咱可以调用它。

print(my_lb(1))

我个人觉得,匿名函数很尴尬,基本上都是用在下面几个高阶函数里面的,如果你平时也想用它,大多数情况下是不符合社区规范的。简单的表达式还行,复杂的表达式可读性太差。

传言 Python 之父 Guido 也不推荐使用它,甚至曾想过移除它,后来放弃了,估计是不好搞。就像 GIL 一样,大家都知道不好,但是这么多年下来太多库都用到了,哪是你想删就能删的,社区不答应,我也不答应。

2、map

map 函数是给一个序列做映射,然后返回结果序列。

简单通俗讲就是:拿到一个序列,给序列中元素一顿操作之后,返回序列。

my_map = map(lambda x: x + 1, [1, 2, 3])
print(my_map)
my_list = list(my_map)
print(my_list)

[2, 3, 4]

你看,map 返回的是一个对象,转 list 之后每个元素的加了1。

3、reduce

reduce 函数就是对一个序列做累积,即将序列中前一个元素和后一个元素进行逻辑组合,然后结果再和后面一个元素组合。

简单通俗讲就是:拿到一个或多个序列,给序列中元素一顿操作之后,返回操作结果。

from functools import reduce

my_rd = reduce(lambda x, y: x + y, [1, 2, 3])
print(my_rd)
6

你看,把列表中的元素都相加了,注意组合关系不一定是相加,你可以换成相乘试试。

乍一看和上面的 map 是一个意思哈,确实用法一样,区别就是 reduce 函数里面的 lambda 函数有两个参数,而 map 函数参数理论上可以多个,但是每个参数对应一个序列,也就是说,有多少个参数,就要有多少个序列。

4、filter

filter 函数用于过滤的,即将序列中的每个元素进行判断,然后返回为 True 的元素。

my_ft = filter(lambda x: x % 2 == 1, [1, 2, 3])
print(my_ft)
my_list = list(my_ft)
print(my_list)

[1, 3]

判断序列中哪些数是奇数,filter 返回的是一个对象,转列表之后,可以看到结果。

5、sorted

sorted 函数用于排序,好多同学可能用过它的参数 reverse=False 升序(默认),reverse=True 降序,但是还有个参数 key 可能没咋用过,这里可以给表达式。

my_st = sorted([1, 5, 3])
print(my_st)
my_st = sorted([1, 5, 3], reverse=True)
print(my_st)
[1, 3, 5]
[5, 3, 1]

数字排序还是挺好用的哈,处理简单的字符串也都可以,但是如果是处理比较复杂字符串排序就有点费劲了,不信试试看:

test_list = ["test_mi_001","test_ki_012","test_go_008","test_lt_003"]

我想让这个列表按照结尾的序号排序:

my_st = sorted(test_list)
print(my_st)
['test_go_008', 'test_ki_012', 'test_lt_003', 'test_mi_001']

排了个寂寞,无论是升序还是降序都是不行的。

所以需要使用参数 key,加表达式:

my_st = sorted(test_list, key=lambda x: x.split("_")[-1])
print(my_st)
['test_mi_001', 'test_lt_003', 'test_go_008', 'test_ki_012']

唉,这就对了,我们在表达式里面将结尾的序号取出来,key 就是关键字,意思就是按照我取出来的关键字排序。这里稍微理解一下哈,里面的表达式比较灵活,你也可以用正则表达式来做:

import re
my_st = sorted(test_list, key=lambda x: re.findall(r"\d+", x))

也都是可以的哈,没毛病。

它不仅可以对列表排序,只要是可迭代对象都可以,列表对象的内建方法 sort 也可以这样用,但区别是 sort 是对原列表进行排序,不返回新列表。

这里再补充一个小知识,我们经常往一个列表中去添加数据,然后对其进行排序,这样做没啥问题,但是如果数据量大了之后,性能会比较低。

维护一个排序序列,建议使用Python 的标准库 bisect 来做,它是采用二分查找算法,性能较高。

6、zip

zip 就是将多个序列打包成一个个元组,然后返回由这些元组组成的列表。

a = [1, 2, 3]
b = [4, 5, 6]
c = zip(a, b)
print(c)
my_list = list(c)
print(my_list)

[(1, 4), (2, 5), (3, 6)]

zip 返回的是一个对象,实际上是一个迭代器对象。

转列表之后,可以看到,相当于是把元素纵向分别取出来,放到一个元组里面,然后元组组成一个列表。做数据处理的时候经常用到,了解一下。

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论