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

通用解法:迭代

如何在列表、字典、集合中根据条件筛选数据?通常我们的做法是使用迭代。

例如针对下面的列表,我们要筛选出其中的非负数,那么通常的做法如下。

1
2
3
4
5
6
7
8
data = [2, -2, 3, 2, 5, 1, -3, 3, 0, 3]
res = []
for x in data:
if x >= 0:
res.append(x)
print res

那么,有没有更加高效优雅的解法呢?

Python 中更优雅的解决方案

列表解析

针对列表中根据条件筛选数据,有两种方法,一是使用filter函数,二是使用更为高效的列表解析。(据代码测试,列表解析的效率是filter函数的两倍。)

1
2
3
4
5
6
7
8
# 筛选出列表中所有的非负数
data = [2, -2, 3, -2, 0, 0, -10, 10, 9, -8]
# 第一种解法:使用 filter() 函数
filter(lambda x: x >= 0, data)
# 第二种解法:列表解析
[x for x in data if x >= 0]

字典解析

针对字典,python中也有高效的字典解析。例如,筛选出字典中所有值大于90的元素,可以采用如下代码。

1
2
3
4
5
6
7
# 筛选出字典中所有值大于90的元素
d = {1: 70, 2: 90, 3: 44, 4: 55, 6: 100, 7: 14, 8: 88, 9: 96, 10: 70}
{k: v for k, v in d.iteritems() if v > 90}
# 嵌套字典
{k: v for k, v in d.iteritems() if v['your key'] > 90}

集合解析

针对集合,我们也有集合解析,形式上与字典解析一致。例如,我们要筛选出集合中所有可以被3整除的数。

1
2
3
4
# 筛选出集合中所有可以被3整除的数
s = {2, -2, 3, 2, 5, 1, -3, 3, 0, 3}
{x for x in s if x % 3 == 0}

iteritems

iteritems Description

Returns an iterator over the dictionary’s (key, value) pairs.

Syntax dict. iteritems()

Return Value iterator

Remarks See also dict.items(). Using iteritems() while adding or deleting entries in the dictionary may raise a RuntimeError or fail to iterate over all entries.

Example

1
2
3
4
5
6
7
8
9
10
>>> d = {'a': 1, 'b': 2}
>>> di = d.iteritems()
>>> di.next()
('a', 1)
>>> di.next()
('b', 2)
>>> di.next()
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
StopIteration

Example 2

1
2
3
4
5
6
7
8
9
>>> d = {'a': 1, 'b': 2}
>>> di = d.iteritems()
>>> di.next()
('a', 1)
>>> d['x'] = 'foobar' # adding a new key:value pair during iterarion;
>>> di.next() # that raises an error later on
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
RuntimeError: dictionary changed size during iteration