什么是高阶函数?
目前,没有一个确定的定义~
一般,大家认为,一个函数可以接收另一个函数作为参数,那么这个函数就是“高阶函数”。
在 python 内置函数中,有一组常用的、操作可迭代对象的高阶函数:
- map()
- filter()
- reduce()
下面我们就以上函数,介绍它们的使用方法。
本文基于python3.9完成。
一、map()
1.1、语法
map(function, iterable, …)
接收两个参数:
参数 | 说明 |
---|---|
function | 一个函数对象 |
iterable | 一个可迭代对象,比如字符串,列表等 |
map 函数,将传入的 function,依次作用于 iterable 的每个元素,并按照 iterable 的顺序,将对应结果组成一个新的迭代器返回。
可以使用 list(),将迭代器转换为列表。
1.2、使用示例
需求:求给出列表中,每一项对应的平方。
def square(x):
# 自定义求平方函数
return x * x
list_demo = [0, 1, 2, 3, 4]
result = map(square, list_demo) # 传入函数对象和可迭代对象,返回一个迭代器
result = list(result) # 通过list()取值
print(result)
输出:
[0, 1, 4, 9, 16]
通常,map() 函数结合匿名函数,可以一行代码完成以上功能:
print(list(map(lambda x: x * x, [0, 1, 2, 3, 4])))
输出:
[0, 1, 4, 9, 16]
二、filter()
2.1、语法
filter(function, iterable)
接收两个参数:
参数 | 说明 |
---|---|
function | 一个函数对象 |
iterable | 一个可迭代对象,比如字符串,列表等 |
filter 函数,用于过滤序列,过滤掉 iterable 中不符合 function 判断条件的元素。
filter() 把传入的 function 依次作用于 iterable 的每个元素,然后根据 function 返回值 True 或 False,决定保留还是丢弃该元素。最后,将返回 True 的元素组成一个迭代器返回。
注意:参数 function,返回的是 True 或 False。所以,最终迭代器中的元素是符合条件的原序列元素。
区分 map() 函数,map返回的是原元素进行一系列操作后的结果。
2.2、使用示例
需求:获取给出列表中的偶数项。
def even(x):
# 查找偶数
if x % 2 == 0:
return True
return False
list_demo = [0, 1, 2, 3, 4]
result = filter(even, list_demo) # 传入函数对象和可迭代对象,返回一个迭代器
result = list(result) # 通过list()取值 print(result) 输出: [0, 2, 4]
通常,filter() 函数结合匿名函数,可以一行代码完成以上功能:
print(list(filter(lambda x: x % 2 == 0, [0, 1, 2, 3, 4])))
输出: [0, 2, 4]
三、reduce()
在 python2 中,reduce() 是一个全局函数,可以直接使用。
在 python3 里,reduce() 已经从全局名字空间移除,被放置在 fucntools 模块里。需要导入后使用:
from functools import reduce
3.1、语法
functools.reduce(function, iterable[, initializer])
接收三个参数:
参数 | 说明 |
---|---|
function | 一个函数对象,必须接收两个参数 |
iterable | 一个可迭代对象,比如字符串,列表等 |
initializer | 可选参数,初始化传入function的第一个参数 |
reduce 函数,将 function 作用在 iterable 上,
首先将 iterable 中的第 1、2 个元素传入 function 进行操作,将得到的结果再与 iterable 的第三个元素传入 function 进行操作。
直到 iterable 的最后一个元素被传入function,最后得到一个返回结果。
如果传入了 initializer,那么首先传的就不是 iterable 的第一个和第二个元素,而是 initializer 和 iterable 的第一个元素。
3.2、使用示例
需求:求给出列表中,所有元素的和。
from functools import reduce
def sum_demo(x, y):
return x + y
list_demo = [0, 1, 2, 3, 4]
result = reduce(sum_demo, list_demo) # 传入函数对象和可迭代对象,返回一个值 print(result)
输出: 10
注意,最终返回的是一个值,不是迭代器!
通常,reduce() 函数结合匿名函数,可以一行代码完成以上功能:
from functools import reduce print(reduce(lambda x, y: x + y, [0, 1, 2, 3, 4])) 输出: 10
当然,求和运算可以直接用 python 内建函数 sum(),没必要动用 reduce。
print(sum([0, 1, 2, 3, 4])) 输出: 10
3.3、示例二
from functools import reduce
scientists = ({'name': 'Alan Turing', 'age': 105, 'gender': 'male'},
{'name': 'Dennis Ritchie', 'age': 76, 'gender': 'male'},
{'name': 'Ada Lovelace', 'age': 202, 'gender': 'female'},
{'name': 'Frances E. Allen', 'age': 84, 'gender': 'female'})
def reducer(accumulator, value):
sum = accumulator + value['age']
return sum
total_age = reduce(reducer, scientists,0)
print(total_age)
print(sum(x['age'] for x in scientists))
a.按性别分组
from functools import reduce
scientists = ({'name': 'Alan Turing', 'age': 105, 'gender': 'male'},
{'name': 'Dennis Ritchie', 'age': 76, 'gender': 'male'},
{'name': 'Ada Lovelace', 'age': 202, 'gender': 'female'},
{'name': 'Frances E. Allen', 'age': 84, 'gender': 'female'})
def group_by_gender(accumulator, value):
accumulator[value['gender']].append(value['name'])
return accumulator
grouped = reduce(group_by_gender, scientists, {'male': [], 'female': []})
print(grouped)
结果如下:
{‘male’: [‘Alan Turing’, ‘Dennis Ritchie’], ‘female’: [‘Ada Lovelace’, ‘Frances E. Allen’]}