在实际项目中可能会遇到下面的简单需求:
1、将 [1,2,-2,43,-35,…] 列表中的负数过滤掉,只保留大于等于0的数;
2、输出 {‘Jim’:78, ‘Tom’:90, ‘Bob’:93, ‘Max’:88} 列表中的考试成绩大于90分的同学;
3、筛选出集合 {6,5,32,33,96,54} 中能被3整除的数;
from random import randint
# [randint(-20,20) for i in range(10)]
# 因为这里的 i 循环过程中并没有用到,所以使用 _ 告诉读程序的人
data = [randint(-20,20) for _ in range(10)]
print(data)
[18, -14, -8, -13, 6, -10, -17, -17, 15, 1]
filter_list = [i for i in data if i>=0]
print(filter_list)
[18, 6, 15, 1]
# filter(function, list) 过滤函数,可返还True和False, list为可迭代对象
filter_data = list(filter(lambda x:x>=0, data))
print(filter_data)
[18, 6, 15, 1]
get_ipython().run_line_magic('timeit', 'filter_list = [i for i in data if i>=0]')
print(filter_list)
773 ns ± 25 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
[18, 6, 15, 1]
get_ipython().run_line_magic('timeit', 'filter_data = list(filter(lambda x:x>=0, data))')
print(filter_data)
1.94 µs ± 69.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
[18, 6, 15, 1]
773 ns 纳秒 和 1.94 µs 微秒
1 µs = 1000000000 ns
结论就是 列表表达式比filter函数要快,所以优先使用表达式
# 初始化一个字典
from random import randint
from pprint import pprint
# 随机生成20个同学的成绩
students = { 'stu_{}'.format(i): randint(50,100) for i in range(1, 21)}
pprint(students)
{'stu_1': 84,
'stu_10': 61,
'stu_11': 66,
'stu_12': 99,
'stu_13': 88,
'stu_14': 78,
'stu_15': 58,
'stu_16': 87,
'stu_17': 88,
'stu_18': 50,
'stu_19': 77,
'stu_2': 75,
'stu_20': 97,
'stu_3': 88,
'stu_4': 70,
'stu_5': 61,
'stu_6': 54,
'stu_7': 70,
'stu_8': 84,
'stu_9': 81}
filter_stu = {k: v for k,v in students.items() if v>=90}
pprint(filter_stu)
{'stu_12': 99, 'stu_20': 97}
filter_stu_list = dict(filter(lambda item: item[1]>=90, students.items()))
print(filter_stu_list)
{'stu_12': 99, 'stu_20': 97}
rand_sets = {randint(1,30) for _ in range(21)}
print(rand_sets)
{5, 7, 8, 9, 11, 13, 16, 17, 18, 21, 23, 24, 26, 28, 29, 30}
sets_filter = {i for i in rand_sets if i%3==0}
print(sets_filter)
{9, 18, 21, 24, 30}
sets_filters = set(filter(lambda x:x%3==0, rand_sets))
print(sets_filters)
{9, 18, 21, 24, 30}