Python filter函数完全指南

原文链接:Python filter函数完全指南

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函数中传入的functionNone,则只对迭代对象中的元素本身判断真假,示例如下:

>>> # 本文由 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']

参考文章列表

  • 7
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值