前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python:过滤序列的filter()函数

Python:过滤序列的filter()函数

作者头像
Exploring
发布2022-09-20 15:01:19
9100
发布2022-09-20 15:01:19
举报
文章被收录于专栏:数据处理与编程实践

文章背景: 最近在学习廖雪峰老师的Python文章,其中有个章节讲到的是filter()函数,该函数用于过滤序列。在学习过程中,也顺带巩固了其它的知识点,在此进行相应的整理。

Python版本:Python 3.7

1 filter()函数

2 示例代码

2.1 保留奇数

2.2 删除序列中的空字符串

2.3 采用函数filter()求数

2.4 采用函数filter()求回数

1 filter()函数

filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。

该函数接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新序列中。

语法:filter(function, iterable)

  • function -- 判断函数。
  • iterable -- 可迭代对象。 返回一个迭代器对象。
2 示例代码
2.1 保留奇数
代码语言:javascript
复制
def is_odd(n):
    return n % 2 == 1

series = [1, 2, 4, 5, 6, 9, 10, 15]
print(list(filter(is_odd, series)))

运行结果:

代码语言:javascript
复制
[1, 5, 9, 15]
2.2 删除序列中的空字符串
代码语言:javascript
复制
def not_empty(s):
    return s and s.strip()

series = ['A', '', 'B', None, 'C', '  ']
print(list(filter(not_empty, series)))

运行结果:

代码语言:javascript
复制
['A', 'B', 'C']

前段代码块的功能是删掉列表中的空字符串,包括None,""和" "。注意函数not_empty()中的代码s and s.strip()

(1)在Python3中,None,0,空字符串,空列表,空字典、空集合都返回False。

(2)针对逻辑运算符and,对于表达式x and y,这里需要这样理解:布尔"与" - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。

x and y 等价于:x if not x else y。请看下面的例子。

代码语言:javascript
复制
x = 0
y = 1
print("x and y =", x and y)
print("x AND y =", x if not x else y)

运行结果:

代码语言:javascript
复制
x and y = 0
x AND y = 0

在运行 and 运算符时,从左到右 进行逻辑运算 (判定输出结果)。一旦遇到 bool 逻辑为 False的值,则立刻返回该值,且不再往后运算;否则,所有元素的 bool 逻辑值均为 True,and 运算符将返回 最后一个值。

(3)回到本节开头的代码s and s.strip()。对于元素None,如果运行方法strip(),程序将报错,'NoneType' object has no attribute 'strip'。所幸的是None本身返回False。因此,对于元素None, s.strip()并不会运行,从而也不会报错。

另外,对于带两个空格的变量' ',该变量返回的布尔值是True,采用s.strip()方法后,得到的是空字符串(布尔值为False),所以,代码行s and s.strip()返回的布尔值也是False。

代码语言:javascript
复制
test = "  "
print(bool(test))
print(bool(test.strip()))

运行结果:

代码语言:javascript
复制
True
False
2.3 采用函数filter()求质数

计算素数的一个方法是埃氏筛法,它的算法可以这么理解:

(1)首先,列出从2开始的所有自然数,构造一个序列。

(2)取序列的第一个数2,它一定是质数,然后用2把序列中2的倍数筛掉。

(3)取新序列的第一个数3,它一定是质数,然后用3把序列中3的倍数筛掉。

(4)取新序列的第一个数5,然后用5把序列中5的倍数筛掉。

(5)取新序列的第一个数7,然后用7把序列中7的倍数筛掉。

如此,不断筛下去,就可以得到所有的质数。

基于上述的算法,得到的代码块如下:

代码语言:javascript
复制
def _odd_iter():
    n = 1
    while True:
        n = n + 2
        yield n

def _not_divisible(n):
    return lambda x: x % n > 0

def primes():
    yield 2
    it = _odd_iter()  # 初始序列
    while True:
        n = next(it)  # 返回序列的第一个数
        yield n
        it = filter(_not_divisible(n), it)  # 构造新序列

# 打印20以内的素数:
for item in primes():
    if item < 20:
        print(item, end=" ")
    else:
        break

运行结果:

代码语言:javascript
复制
2 3 5 7 11 13 17 19 

(1) 函数_odd_iter()中,由于存在yield关键字,因此,得到的是一个生成器,构造的是一个从3开始的奇数序列,并且它是无限序列。关于yield用法的解析,请查阅文末的参考资料[6]。

(2) 函数_not_divisible(n)中,构造的是一个筛选函数。其中,存在参数n,因为每次的除数都在变化。

(3) 函数primes()中,同样存在yield关键字,因此,得到的也是一个生成器,一开始返回质数2,后来通过filter()不断产生筛选后新的序列,并且也是一个无限序列。

(4)由于通过函数prime()得到的是一个无限序列,所以调用时需要设置一个退出循环的条件。本代码块要实现的目标是:输出20以内的所有质数。

(5)在for循环中,一开始先进入函数primes(),运行到代码行yield 2,返回数字2,退出函数primes()。所以一开始输出的数字是2。然后继续进入函数primes(),接着代码yield 2,运行之后的代码。将函数_odd_iter()赋值给变量it,得到一个生成器(从3开始的奇数序列)。

(6) 然后进入while循环,针对生成器it,使用next方法。这个时候,进入函数_odd_iter(),返回数字3,退出函数_odd_iter()。继续回到函数primes()中,将3赋给变量n。然后返回数字3,退出函数primes()。所以第二个输出的数字是3。

(7)继续进入函数primes(),接着代码yield n,运行之后的代码。目前变量n的值是3,变量it是从3开始的奇数序列,通过filter筛选(去掉3的倍数)后,得到的是5开始的序列,将该序列重新赋给变量it。在while循环内继续运行。针对生成器it,使用next方法。这个时候,返回变量it这个生成器的第一个值,也就是5,将5赋给变量n。然后返回数字5,退出函数primes()。所以第三个输出的数字是5。

(8) 继续进入函数primes(),接着代码yield n,运行之后的代码。目前变量n的值是5,变量it是从5开始的序列,通过filter筛选(去掉5的倍数)后,得到的是7开始的序列,将该序列重新赋给变量it。继续在while循环内继续运行。针对生成器it,使用next方法。这个时候,返回变量it这个生成器的第一个值,也就是7,将7赋给变量n。然后返回数字7,退出函数primes()。所以第四个输出的数字是7。

(9)如此反复,直到返回的变量item大于20时,退出for循环。

2.4 采用函数filter()求回数

回数是指从左向右读和从右向左读都是一样的数,例如12321909

获取100~200范围内的所有回数,可以通过下面的代码块实现。

代码语言:javascript
复制
def is_palindrome(n):
    return str(n) == str(n)[::-1]

output = filter(is_palindrome, range(100, 200))
print(list(output))

运行结果:

代码语言:javascript
复制
[101, 111, 121, 131, 141, 151, 161, 171, 181, 191]

获取某个字符串倒数后的结果,可以通过切片器(Slicing)实现。

代码语言:javascript
复制
var_st = "python"
string_length = len(var_st)

print(var_st[0:string_length:1])
print(var_st[string_length::-1])
print(var_st[string_length-1::-1])
print()
print(var_st[string_length-2::-1])
print(var_st[::-1])

运行结果:

代码语言:javascript
复制
python
nohtyp
nohtyp

ohtyp
nohtyp

参考资料:

[1] filter(https://www.liaoxuefeng.com/wiki/1016959663602400/1017404530360000)

[2] Python3 filter() 函数(https://www.runoob.com/python3/python3-func-filter.html)

[3] Python 逻辑判断True/False的坑(https://www.biaodianfu.com/python-true-false.html)

[4] Python 运算符(https://www.runoob.com/python/python-operators.html)

[5] 详解 逻辑运算符 (and / or / not) + 布尔逻辑 (bool)(https://blog.csdn.net/qq_39478403/article/details/105654170#2.2%20and%20%E2%80%94%E2%80%94%20bool%20%E2%80%9C%E4%B8%8E%E2%80%9D%20%E9%80%BB%E8%BE%91%E8%BF%90%E7%AE%97%E7%AC%A6)

[6] Python: yield用法的解析

[7] How do you reverse a string in Python(https://www.educative.io/edpresso/how-do-you-reverse-a-string-in-python)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据处理与编程实践 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 filter()函数
  • 2 示例代码
    • 2.1 保留奇数
      • 2.2 删除序列中的空字符串
        • 2.3 采用函数filter()求质数
          • 2.4 采用函数filter()求回数
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档