每天5分钟玩转Python(14) - 函数式编程之filter/sorted

这一篇再讲两个高阶函数,一个是过滤器函数filter,一个是排序函数sorted。这些都是使用最频繁的函数,也很具有代表性。

filter()函数

filter()函数用于过滤序列,跟map()一样,也是接受一个函数,一个Iterable。 它将传入的函数依次作用于序列每个元素如果函数返回值为True则保留元素,否则丢弃元素。 最终的返回值仍然是一个Iterable

比如在一个从0到10的列表中,只保留偶数。则正是过滤器函数用武之地:

1
print(list(filter(lambda x: x % 2 == 1, range(0, 11))))

把一个序列中的冒号删掉,可以这么写:

1
print(list(filter(lambda x: x != ':', ['a', 'b', ':', 'c', ':', '!'])))

运行后结果显示:

1
['a', 'b', 'c', '!']

sorted()函数

排序是我们经常要用到的功能,不管是冒泡还是快速排序、堆排序这些都需要比较元素的大小。 如果是数字我们直接比较值就可以,但如果是字典或者更加复杂的对象类型比较呢?这时候就需要通过函数将比较逻辑抽出来。

sorted()函数接受一个可迭代对象、可选比较函数参数实现排序,返回结果是一个列表。

如果是普通的数字、字符可以直接比较值得,那么直接使用sorted()函数即可:

1
print(sorted((2, 1, 5, 3, 4)))

输出结果:

1
[1, 2, 3, 4, 5]

如果要反向排序,就是从大到小,则加一个关键字参数reverse=True即可:

1
print(sorted((2, 1, 5, 3, 4), reverse=True))

如果要自定义比较逻辑,可以传入一个比较函数来实现自定义排序,比较函数的定义是:传入两个待比较的元素 x, y, 如果 x 应该排在 y 的前面,返回 -1,如果 x 应该排在 y 的后面,返回 1。如果 x 和 y 相等,返回 0。

比如如果我们要对字典中的value按照绝对值大小进行比较,则可以这样写:

1
2
d = {'zhangsan': -22, 'lisi': 13, 'wangwu:': 16}
print(sorted(d.items(), key=lambda item: abs(item[1])))

注意,我先将字典转成可迭代对象,每个元素是一个二元组,第一个元素为key,第二个元素为value。 然后传入一个lambda函数作为比较函数,这个比较函数取第二个value元素的绝对值做比较。

最后运行结果如下:

1
[('lisi', 13), ('wangwu:', 16), ('zhangsan', -22)]

可以看出的确是按照值的绝对值从小到大排序了。