Python5个常用高阶函数:map、filter、sorted、reduce、zip

Python5个常用高阶函数:map、filter、sorted、reduce、zip

目录

    • 1. `map` —— 映射
    • 2. `filter` —— 过滤
    • 3. `sorted` —— 排序
    • 4. `reduce` —— 规约/累积
    • 5. `zip` —— 拉链/配对
    • 综合示例
    • 总结

1.map—— 映射

作用:对可迭代对象中的每个元素应用同一个函数,返回一个迭代器。

语法map(function, iterable, ...)

注意

  • 返回的是迭代器,可用list()转换为列表
  • 可以同时处理多个可迭代对象,函数接收几个参数就传几个可迭代对象
  • 长度以最短的可迭代对象为准

示例

# 把列表中所有数字平方nums=[1,2,3,4,5]squared=map(lambdax:x**2,nums)print(list(squared))# [1, 4, 9, 16, 25]# 多个可迭代对象:对应位置相加a=[1,2,3]b=[10,20,30]summed=map(lambdax,y:x+y,a,b)print(list(summed))# [11, 22, 33]# 用内置函数words=["hello","world"]upper_words=map(str.upper,words)print(list(upper_words))# ['HELLO', 'WORLD']

2.filter—— 过滤

作用:根据判断函数的真假,筛选出可迭代对象中符合条件的元素。function返回True保留该元素

语法filter(function, iterable)

注意

  • 如果function=None,则直接去掉所有假值0, "", None, False, []等)

示例

# 过滤出偶数nums=[1,2,3,4,5,6,7,8]evens=filter(lambdax:x%2==0,nums)print(list(evens))# [2, 4, 6, 8]# 过滤空字符串strings=["hello","","world","","python"]non_empty=filter(lambdas:len(s)>0,strings)print(list(non_empty))# ['hello', 'world', 'python']# 过滤掉 Nonedata=[1,None,3,None,5]clean=filter(lambdax:xisnotNone,data)print(list(clean))# [1, 3, 5]# 用 None 作为函数:过滤掉所有假值(0, "", None, False 等)mixed=[0,1,"","hello",False,True,None]truthy=filter(None,mixed)print(list(truthy))# [1, 'hello', True]

3.sorted—— 排序

作用:对可迭代对象进行排序。

语法sorted(iterable, key=None, reverse=False)

说明

  • 返回一个新列表(原对象不变)(区别于list.sort()原地排序)
  • key参数接收一个函数,作用到每个元素上,按作用后的结果排序
  • 稳定排序:相同 key 值的元素保持原始顺序

示例

# 基础排序nums=[3,1,4,1,5,9,2,6]print(sorted(nums))# [1, 1, 2, 3, 4, 5, 6, 9]# 按绝对值排序nums=[3,-1,4,-5,2]print(sorted(nums,key=abs))# [-1, 2, 3, 4, -5]# 按字符串长度排序words=["banana","apple","kiwi","pear","orange"]print(sorted(words,key=len))# ['kiwi', 'pear', 'apple', 'banana', 'orange']# 先按长度,再按字母(元组排序)print(sorted(words,key=lambdas:(len(s),s)))# ['kiwi', 'pear', 'apple', 'banana', 'orange']# 降序print(sorted(nums,reverse=True))# [4, 3, 2, -1, -5]# 对字典按 value 排序d={"a":3,"b":1,"c":2}sorted_items=sorted(d.items(),key=lambdax:x[1])print(sorted_items)# [('b', 1), ('c', 2), ('a', 3)]

4.reduce—— 规约/累积

作用:对可迭代对象中的元素反复应用一个二元函数,将序列缩减为一个值。

语法functools.reduce(function, iterable, initializer=None)

示例

fromfunctoolsimportreduce# 累加求和nums=[1,2,3,4,5]total=reduce(lambdax,y:x+y,nums)print(total)# 15# 执行过程:((((1+2)+3)+4)+5) = 15# 累乘product=reduce(lambdax,y:x*y,nums)print(product)# 120# 找最大值max_val=reduce(lambdax,y:xifx>yelsey,nums)print(max_val)# 5# 带初始值nums=[1,2,3]total=reduce(lambdax,y:x+y,nums,10)print(total)# 16 (10 + 1 + 2 + 3)# 字符串拼接words=["Hello"," ","World","!"]sentence=reduce(lambdax,y:x+y,words)print(sentence)# 'Hello World!'# 列表扁平化nested=[[1,2],[3,4],[5,6]]flat=reduce(lambdax,y:x+y,nested)print(flat)# [1, 2, 3, 4, 5, 6]

特点

  • 需要从functools导入
  • 执行过程:f(...f(f(init, seq[0]), seq[1]), ...seq[n-1])
  • initializer时,先从它开始累积
  • 空序列不带初始值会报错

5.zip—— 拉链/配对

作用:将多个可迭代对象"并行"打包,对应位置的元素组成元组。

语法zip(iterable1, iterable2, ...)

示例

# 两列表配对names=["Alice","Bob","Charlie"]ages=[25,30,35]paired=zip(names,ages)print(list(paired))# [('Alice', 25), ('Bob', 30), ('Charlie', 35)]# 多列表配对a=[1,2,3]b=[10,20,30]c=[100,200,300]print(list(zip(a,b,c)))# [(1, 10, 100), (2, 20, 200), (3, 30, 300)]# 长度不一致:以最短为准x=[1,2,3,4]y=["a","b","c"]print(list(zip(x,y)))# [(1, 'a'), (2, 'b'), (3, 'c')] 4 被丢弃# 创建字典keys=["name","age","city"]values=["Alice",25,"Shanghai"]d=dict(zip(keys,values))print(d)# {'name': 'Alice', 'age': 25, 'city': 'Shanghai'}# 同时遍历多个列表names=["Alice","Bob","Charlie"]scores=[85,92,78]forname,scoreinzip(names,scores):print(f"{name}:{score}")# Alice: 85# Bob: 92# Charlie: 78

特点

  • 返回迭代器,用list()或循环消费
  • 长度取最短的可迭代对象(严格模式用zip_longest
  • zip(*zipped)可以"解压缩"还原(相当于转置)
  • 常用于并行遍历构建字典矩阵转置
# 解压缩pairs=[(1,'a'),(2,'b'),(3,'c')]nums,letters=zip(*pairs)print(nums)# (1, 2, 3)print(letters)# ('a', 'b', 'c')

综合示例

fromfunctoolsimportreduce# 数据students=[{"name":"Alice","math":85,"english":90},{"name":"Bob","math":78,"english":85},{"name":"Charlie","math":92,"english":88},]# 1. map: 给每人加一个 total 字段students_with_total=list(map(lambdas:{**s,"total":s["math"]+s["english"]},students))# 2. filter: 筛选 total > 170top_students=list(filter(lambdas:s["total"]>170,students_with_total))# 3. sorted: 按 total 降序排列ranked=sorted(top_students,key=lambdas:s["total"],reverse=True)# 4. zip: 提取名字和总分names=[s["name"]forsinranked]scores=[s["total"]forsinranked]ranking=list(zip(range(1,len(names)+1),names,scores))# 5. reduce: 计算平均总分avg_total=reduce(lambdax,y:x+y,scores)/len(scores)print("排名:",ranking)print("平均总分:",avg_total)# 排名: [(1, 'Charlie', 180), (2, 'Alice', 175)]# 平均总分: 177.5

总结

函数用途输入输出
map(f, iter)对每个元素应用函数函数 + 可迭代对象新迭代器
filter(f, iter)筛选符合条件的元素函数 + 可迭代对象新迭代器
sorted(iter, key)排序可迭代对象 + key 函数新列表
reduce(f, iter)累积计算为单个值二元函数 + 可迭代对象单个值
zip(*iters)并行配对多个可迭代对象元组迭代器