高阶内置函数
约 1758 字大约 6 分钟
2025-04-04
这一部分主要是一些 Python 中内置的高阶函数。所谓的高阶函数,就是以函数为参数的函数。
- filter
- map
- sorted
- max 和 min
- 1写一段 map(lambda x: x*2, lst),再用列表推导式 [x*2 for x in lst] 写一遍 —— 推导式更地道。
- 2用 filter(None, seq) 一次性去掉所有“假值”(0、None、空串),是最优雅的清洗写法。
- 3对 dict 用 sorted(d.items(), key=lambda kv: kv[1]) 按 value 排序,体会 key 参数的威力。
- 4用 sorted(records, key=lambda r: (r['age'], r['name'])) 做多字段排序 —— 返回元组实现二次键。
- 5用 dict(zip(keys, values)) 一行构造字典,是 zip 最常见的应用。
这一部分主要是一些 Python 中内置的高阶函数。所谓的高阶函数,就是以函数为参数的函数。
filter
filter 函数用来过滤掉不符合条件的元素。filter 函数有两个参数,第一个参数为规则函数,第二个参数为可迭代对象:
python playground
lst = [1, 2, 3, 4, 5, 6, 7, 8]
def foo(x): # 规则函数
return x > 4 # 规则函数的返回值需要是布尔值
print(filter(foo, lst)) # <filter object at 0x000002B53EA8AB00>
print(list(filter(foo, lst))) # [5, 6, 7, 8]filter 的返回值为 filter 对象,可迭代,可以通过 list 函数转化为列表。
我们可以通过 for 循环模拟内置函数 filter:
def filter(func, iter):
lst = []
for i in iter:
if func(i):
lst.append(i)
return lst也可以使用匿名函数作为规则函数,这样可以让代码看起来非常简洁:
python playground
# 找到年纪大于16岁的人的信息
lst = [
{'id': 1,'name': 'alice','age': 18},
{'id': 2,'name': 'bob','age': 17},
{'id': 3,'name': 'tom','age': 16},
]
# 过滤条件
print(list(filter(lambda x: x['age'] > 16, lst))) # [{'id': 1, 'name': 'alice', 'age': 18}, {'id': 2, 'name': 'bob', 'age': 17}]map
map 函数也称作映射函数,用来将可迭代对象中每个元素执行函数功能:
python playground
lst = [1, 2, 3, 4, 5, 6, 8, 9]
print(map(str, lst)) # <map object at 0x000001ABD67EA908>
print(list(map(str, lst))) # ['1', '2', '3', '4', '5', '6', '8', '9']map 函数返回的是 map 对象,也可以使用 list 函数转换为列表。
map 函数可以使用更多参数的规则函数来整合多个可迭代对象:
python playground
lst1 = [1,2,3]
lst2 = [3,2,1]
lst3 = [3,2,1,5]
print(list(map(lambda x, y, z: x + y + z, lst1, lst2, lst3))) # [7, 6, 5]如果可迭代对象长度不同,map 函数的迭代次数以最短的可迭代对象为准。
sorted
sorted 函数用来将可迭代对象排序:
python playground
print(sorted('alice,bob')) # 升序 [',', 'a', 'b', 'b', 'c', 'e', 'i', 'l', 'o']
print(sorted(('alice','bob'), reverse=True)) # 降序 ['bob', 'alice']
dic = {1: 'a', 3: 'c', 2: 'b'}
print(sorted(dic)) # [1, 2, 3]不管输入的可迭代对象是什么样的数据类型,sorted 函数的返回值都是一个列表。
sorted 函数也可以使用规则函数,只是这次规则函数要通过使用关键字参数的方式引入:
python playground
lst = ['天龙八部', '西游记', '红楼梦', '三国演义']
print(sorted(lst,key=len)) # ['西游记', '红楼梦', '天龙八部', '三国演义']
print(sorted(lst,key=lambda x: len(x))) # ['西游记', '红楼梦', '天龙八部', '三国演义']
lst = [
{'id': 1,'name': 'alice','age': 18},
{'id': 2,'name': 'bob','age': 17},
{'id': 3,'name': 'tom','age': 16},
]
print(sorted(lst,key=lambda x: x['age'], reverse=True))
# [{'id': 1, 'name': 'alice', 'age': 18}, {'id': 2, 'name': 'bob', 'age': 17}, {'id': 3, 'name': 'tom', 'age': 16}]}]列表的 .sort() 方法是在列表所在的原地进行修改,而 sorted 函数则是新建一个列表:
python playground
lst = [1, 2, 3, 4, 65, -7]
print(sorted(lst)) # [-7, 1, 2, 3, 4, 65]
print(lst) # [1, 2, 3, 4, 65, -7]
lst1 = [1, 2, 3, 4, 65, -7]
print(lst1.sort()) # None
print(lst1) # [-7, 1, 2, 3, 4, 65]max 和 min
max 和 min 函数用来选取可迭代对象中的最大值或最小值,可以指定规则函数进行更复杂的选择:
python playground
lst = [1, 2, 3, 4, 5, 6, -9, 10, -22]
print(max(lst)) # 10
print(min(lst, key=abs)) # 1
print(max(lst, key=lambda x: pow(x, 4) - pow(x, 2) + x)) # -22也可以通过这两个函数找到最大的值或者最小的值对应的键:
python playground
dic = {'a': 3, 'b': 2, 'c': 1}
print(max(dic.values())) # 3
print(min(dic, key=lambda x: dic[x])) # creduce
reduce 函数用来进行累运算。规则函数中会有两个参数,第一个参数用来存储上一次运算的结果,第二个参数传入下一个值,返回值为运算操作。
需要注意的是,在 Python2 中,reduce 可以直接使用,而在 Python3 中,需要在 functools 里面导入 reduce 函数:
from functools import reduce我们可以通过 reduce 函数实现累乘运算:
python playground
from functools import reduce
def func(x, y):
return x * y
print(reduce(func, range(1, 6))) # 120将函数用匿名函数整合会让代码更加简洁:
python playground
from functools import reduce
print(reduce(lambda x, y: x * y, range(1, 6)))zip
zip 是拉链的意思,用来将两个可迭代对象以关联起来,以返回值为 zip 对象,可以转换为列表,列表中的每个元素为原来的可迭代对象中的元素组成的元组:
python playground
lst1 = [1, 2, 3, 4, 5]
lst2 = [5, 4, 3, 2, 1]
print(zip(lst1, lst2)) # <zip object at 0x0000021A6A792B48>
print(list(zip(lst1, lst2))) # [(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)]使用 map 函数也可以实现类似的功能:
python playground
lst1 = [1, 2, 3, 4, 5]
lst2 = [5, 4, 3, 2, 1]
print(list(map(lambda x, y: (x, y), lst1, lst2))) # [(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)]这种数据类型可以直接使用 dict 函数转换为字典:
python playground
lst1 = [1, 2, 3, 4, 5]
lst2 = [5, 4, 3, 2, 1]
print(dict(zip(lst1, lst2))) # {1: 5, 2: 4, 3: 3, 4: 2, 5: 1}高阶内置函数总结
| 函数名 | 规则函数位置 | 规则函数形参数目 | 返回值数据类型 |
|---|---|---|---|
| filter | 首位 | 1 个 | filter 对象,可转换为列表 |
| map | 首位 | 1 个或多个 | map 对象,可转换为列表 |
| reduce | 首位 | 2 个 | 可迭代对象中的元素 |
| max和min | 末尾,用 key 指明 | 1 个 | 可迭代对象中的元素 |
| sorted | 末尾,用 key 指明 | 1 个 | 列表 |
| zip | 无 | 无 | zip 对象,可转换为列表或字典 |
- 高阶函数 = 把函数当参数;filter/map 返回的是“惰性对象”,要消费必须 list() 或 for。
- 复杂筛选/映射写法选择:推导式 > map/filter + lambda > 显式 for —— 看可读性。
- sorted/max/min 都接受 key=函数 做“按什么排/找”,返回元组可实现多字段排序。
- reduce 在 3 里要从 functools 导入,多数累积场景下 sum/min/max/any/all 已经够用。
- zip 把若干序列并成对组,dict(zip(keys, vals)) 是构造字典最简洁的写法。
版权所有
版权归属:Shuo Liu
