1、简介
描述
filter翻译过来为过滤、筛选,通过名称我们可以确定filter()函数主要的功能是过滤。
filter()
属于Python中的内置函数,用于过滤序列,过滤掉不符合条件的元素。传入一个可迭代对象并返回一个新的迭代器对象,如果要转换为列表,可以使用list()
来转换。该函数提供了一种有用的、可重复的方式来过滤Python中的序列。
语法:
以下是filter()方法的语法
filter(
function, # The function to filter items with
iterable # The iterable to filter
)
参数:
- function:判断函数
- iterable:可迭代对象
返回值:
返回一个迭代器对象Iterator
。
通过语法可以发现filter()
接收一个函数和序列,把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
如果传入的函数是None
,则不调用任何函数,只对迭代对象中的元素本身判断真假,保留为真的元素。
filter()
函数返回的是一个Iterator
,也就是一个惰性序列,所以要强迫filter()
完成计算结果,需要用list()
函数获得所有结果并返回list.
2、不使用filter的情况下如何过滤列表
假设我们有以下列表:[1,2,3,4,5,6,7,8,9]
并且我们希望过滤列表获取所有大于5的元素。我们可以通过for循环的方式实现该操作
>>> # somirror.com 编辑发表文章
>>> values = [1,2,3,4,5,6,7,8,9]
>>> filtered = []
>>> for value in values:
... if value > 5:
... filtered.append(value)
...
>>> print(filtered)
[6, 7, 8, 9]

在上述代码中我们主要做了如下几个操作。
- 创建了一个空列表
filtered
,该列表用于保存结果。 - 遍历
values
中的每一个值。 - 在循环中判断值是否大于5,如果大于5则添加到
filtered
中。
通过该方法可以实现我们的需求,但并不是最好的实现方式,主要有如下原因:
- 我们需要先创建一个空的列表用于保存过滤后的值。
- 该方法仅适合完成一次性任务,如果我们需要使用相同的规则过滤另外一个列表,则需要重写。
我们可以发现使用for循环的方式过滤列表是有一些缺点的,filter()
函数可以简化该任务。
3、使用filter函数在Python中过滤列表
使用Python filter()函数过滤列表会使过程更简单和更Pythonic。
filter()函数将函数和序列作为参数,所以我们需要先定义一个函数,根据我们想要过滤的条件返回一个布尔值,然后我们可以将这个函数传递给filter()
函数。
>>> # somirror.com 整理编辑发布本文
>>> values = [1,2,3,4,5,6,7,8,9]
>>> def greater_than_five(x):
... return x > 5
...
>>> filtered = filter(greater_than_five, values)
>>> filtered_values = list(filtered)
>>> print(filtered_values)
[6, 7, 8, 9]

在上述代码中,我们主要做了如下的操作:
- 我们定义了一个函数,
greater_than_five()
它以单个值作为输入。该函数将参数与5比较后返回布尔值。 - 然后我们通过传入函数的可调用对象(不带括号)和列表本身来创建一个新的过滤器对象。
- 然后,我们从这个过滤器对象中创建了一个列表,以返回结果。
我们可以看到这种方法更具有目的性——它直接传达你在做什么。该filter()
函数的目的是过滤数据。当我们使用for循环时,这种方法并不清晰。
如果filter函数中传入的function
为None
,则只对迭代对象中的元素本身判断真假,示例如下:
>>> # 本文由 somirror.com 整理编辑
>>> values = [0,1,2,3,4]
>>> filtered = list(filter(None,values))
>>> filtered
[1, 2, 3, 4]

通过改示例我们可以发现0被过滤掉了,因为0的真假值为False
。
4、匿名Lambda函数与Python filter()结合使用
在很多情况下我们可能仅仅过滤一个列表,不用过滤其他内容。通过使用lambda函数消除了很多关于函数用途的歧义。
>>> # 本文由 somirror.com 整理编辑
>>> values = [1,2,3,4,5,6,7,8,9]
>>> filtered = filter(lambda x:x>5, values)
>>> filtered_values = list(filtered)
>>> print(filtered_values)
[6, 7, 8, 9]

我们可以发现这段代码简短了一些,因为lambda函数是在filter()
函数本身内定义的,所以代码的意图更加清晰。
5、用列表推导取代filter
如果你学习过列表推导一定会觉得上述使用filter的示例代码还是有些复杂不够pythonic。
Python里面有一种很精简的写法,可以根据某个序列或可迭代对象派生出一份新的列表。用这种写法写成的表达式,叫做列表推导(list comprehension)。
上述代码我们可以修改为列表推导,代码如下:
>>> # 本文由 somirror.com 整理编辑
>>> values = [1,2,3,4,5,6,7,8,9]
>>> filtered = [ value for value in values if value > 5 ]
>>> filtered
[6, 7, 8, 9]

可以发现使用列表推导更加的简单明了,也更符合Pythonic精神。
字典与集合也有相应的推导机制,分别叫做字典推导(dictionary comprehension)与集合推导(set comprehension)。
在《Effective Python:编写高质量Python代码的90个有效方法》一书中,第27条就建议我们用列表推导取代map与filter。主要原因有以下几点:
- 列表推导要比内置的map与filter函数清晰,因为它不用另外定义lambda表达式。
- 列表推导可以很容易地跳过原列表中的某些数据,假如改用map实现,那么必须搭配filter才能实现。
- 字典与集合也可以通过推导来创建。
在《流畅的Python》一书中也表明“在Python 3中,map和filter还是内置函数,但是由于引入了列表推导和生成器表达式,它们变得没那么重要了“(第五章–5.2高阶函数–map、filter和reduce的现代替代品)。
6、Python filter函数、列表推导示例
本节主要介绍filter
如何过滤字典、元组、字符串,以及如何将相应的代码使用列表推导实现。
使用filter函数过滤偶数
该示例中将展示如何返回列表中所有偶数。我们可以使用%
进行模运算。该运算符返回除法的余数,如果余数为0则为偶数。
>>> # 本文由 somirror.com 整理编辑
>>> values = [1,2,3,4,5,6,7,8,9]
>>> filtered = list(filter(lambda x:x%2 == 0, values))
>>> filtered
[2, 4, 6, 8]

使用列表推导过滤偶数
>>> # 本文由 somirror.com 整理编辑
>>> values = [1,2,3,4,5,6,7,8,9]
>>> filtered = [value for value in values if value % 2 == 0 ]
>>> filtered
[2, 4, 6, 8]

Filter过滤 Python 列表中超过 n 个字符的单词
该示例主要介绍过滤字符串列表中指定长度的字符串。
>>> # 本文由 somirror.com 整理编辑
>>> strings = ['hello', 'world', 'yes', 'no', 'maybe']
>>> filtered = list(filter(lambda x: len(x) > 4, strings))
>>> filtered
['hello', 'world', 'maybe']

列表推导过滤 Python 列表中超过 n 个字符的单词
>>> # 本文由 somirror.com 整理编辑
>>> strings = ['hello', 'world', 'yes', 'no', 'maybe']
>>> filterd = [x for x in strings if len(x) > 4 ]
>>> filterd
['hello', 'world', 'maybe']

参考文章列表
- Python官方文档
- 菜鸟教程
- datagy
- 廖雪峰的官方网站
- 《Effective Python:编写高质量Python代码的90个有效方法(原书第二版》
- 《流畅的Python》
原创文章,作者:somirror,如若转载,请注明出处:https://somirror.com/3522.html