在列表、字典、集合中筛选数据

Python进阶笔记

Posted by Cheereus on July 5, 2020

对数据进行筛选是编程中非常频繁的操作,例如筛选出列表中的非负数、筛选出字典中键值大于 0 的项、筛选出集合中能被 3 整除的数等。

在 Python 中有一些非常简便的写法,在此做一点总结。

在列表中根据条件筛选数据

最普通的方法是使用 for 循环遍历:

data = [-1, 2, 3, -4, 5]
# 筛选出其中的非负数
res = []
for x in data:
    if x >= 0:
        res.append(x)

print(res)
# 输出 [2, 3, 5]

这种方法很啰嗦,效率也很低,而 Python 中提供了列表解析和 filter 函数的方法。

先来看列表解析:

from random import randint

# 生成一个含有 10 个随机数的列表
l = [randint(-10, 10) for _ in range(10)]
# 下划线和 i 一样,只是个临时的循环变量,使用下划线相当于明确指出这个变量没有其他作用
# [5, 0, 4, 5, -1, -1, 2, 6, -7, -5]

# 使用列表解析进行筛选
[x for x in l if x >= 0]
# [5, 0, 4, 5, 2, 6]

然后来看 filter 函数:

l = [5, 0, 4, 5, -1, -1, 2, 6, -7, -5]
# filter 函数接收两个参数,第一个参数为过滤函数,第二个参数为过滤对象
g = filter(lambda x: x>=0, l)
# filter 函数在 Python3 开始会返回一个生成器对象
# 生成器对象使用 next() 获取每一个元素
# 将生成器对象直接传给 list 构造器即可
list(g)

对于简单的筛选功能,推荐列表解析,更加简单而且速度更快一些。

在字典中根据条件筛选数据

先来用字典解析进行筛选:

# 生成一个有 20 个键值对的学生成绩字典
d = {'student%d' % i: randint(50, 100) for i in range(1,21)}

# 筛选分数高于 90 的项
{k:v for k, v in d.items() if v >= 90}

再来用 filter 函数进行筛选:

# 得到生成器对象
g = filter(lambda item: item[1] >= 90, d.items())

# 传给字典构造器来获得过滤后的字典
dict(g)

在集合中根据条件筛选数据

使用集合解析:

# 生成一个随机数集合
s = {randint(0, 20) for _ in range(20)}

# 筛选能被 3 整除的数
{x for x in s if x % 3 == 0}
# {0, 6, 15, 18}