带有 filter() 函数的 Lambda
Python 中的 filter() 函数需要两个参数:
- 定义过滤条件的函数
- 函数在其上运行的可迭代对象
运行该函数,我们得到一个过滤器对象:
lst = [33, 3, 22, 2, 11, 1]
filter(lambda x: x > 10, lst)
Output:
<filter at 0x250cb090520>
为了从过滤器对象中获取一个新的迭代器,并且原始迭代器中的所有项都满足预定义的条件,我们需要将过滤器对象传递给 Python 标准库的相应函数:list()、tuple()、set ()、frozenset() 或 sorted()(返回排序列表)
让我们过滤一个数字列表,只选择大于 10 的数字并返回一个按升序排序的列表:
lst = [33, 3, 22, 2, 11, 1]
sorted(filter(lambda x: x > 10, lst))
Output:
[11, 22, 33]
我们不必创建与原始对象相同类型的新可迭代对象,此外我们可以将此操作的结果存储在一个变量中:
lst = [33, 3, 22, 2, 11, 1]
tpl = tuple(filter(lambda x: x > 10, lst))
tpl
Output:
(33, 22, 11)
带有 map() 函数的 Lambda
我们使用 Python 中的 map() 函数对可迭代的每个项目执行特定操作。它的语法与 filter() 相同:一个要执行的函数和一个该函数适用的可迭代对象。
map() 函数返回一个 map 对象,我们可以通过将该对象传递给相应的 Python 函数来从中获取一个新的迭代:list()、tuple()、set()、frozenset() 或 sorted()
与 filter() 函数一样,我们可以从 map 对象中提取与原始类型不同类型的可迭代对象,并将其分配给变量。
下面是使用 map() 函数将列表中的每个项目乘以 10 并将映射值作为分配给变量 tpl 的元组输出的示例:
lst = [1, 2, 3, 4, 5]
print(map(lambda x: x * 10, lst))
tpl = tuple(map(lambda x: x * 10, lst))
tpl
Output:
<map object at 0x00000250CB0D5F40>
(10, 20, 30, 40, 50)
map() 和 filter() 函数之间的一个重要区别是第一个函数总是返回与原始函数相同长度的迭代。因此由于 pandas Series 对象也是可迭代的,我们可以在 DataFrame 列上应用 map() 函数来创建一个新列:
import pandas as pd
df = pd.DataFrame({'col1': [1, 2, 3, 4, 5], 'col2': [0, 0, 0, 0, 0]})
print(df)
df['col3'] = df['col1'].map(lambda x: x * 10)
df
Output:
col1 col2
0 1 0
1 2 0
2 3 0
3 4 0
4 5 0
col1 col2 col3
0 1 0 10
1 2 0 20
2 3 0 30
3 4 0 40
4 5 0 50
当然要在上述情况下获得相同的结果,也可以使用 apply() 函数:
df['col3'] = df['col1'].apply(lambda x: x * 10)
df
Output:
col1 col2 col3
0 1 0 10
1 2 0 20
2 3 0 30
3 4 0 40
4 5 0 50
带有 reduce() 函数的 Lambda
reduce() 函数与 functools Python 模块相关,它的工作方式如下:
- 对可迭代对象的前两项进行操作并保存结果
- 对保存的结果和可迭代的下一项进行操作
- 以这种方式在值对上进行,直到所有项目使用可迭代的
该函数与前两个函数具有相同的两个参数:一个函数和一个可迭代对象。但是与前面的函数不同的是,这个函数不需要传递给任何其他函数,直接返回结果标量值:
from functools import reduce
lst = [1, 2, 3, 4, 5]
reduce(lambda x, y: x + y, lst)
Output:
15
上面的代码展示了我们使用 reduce() 函数计算列表总和时的作用
需要注意的是,reduce() 函数总是需要一个带有两个参数的 lambda 函数,而且我们必须首先从 functools Python 模块中导入它
Python 中 Lambda 函数的优缺点
优点
- 评估单个表达式的理想选择,应该只评估一次
- 它可以在定义后立即调用
- 与相应的普通语法相比,它的语法更紧凑
- 它可以作为参数传递给高阶函数,例如 filter()、map() 和 reduce()
缺点
- 它不能执行多个表达式
- 它很容易变得麻烦,可读性差,例如当它包括一个 if-elif-...-else 循环
- 它不能包含任何变量赋值(例如,lambda x: x=0 将抛出一个语法错误)
- 我们不能为 lambda 函数提供文档字符串