高阶函数
filter(function,iterable)
过滤器,过滤掉不满足函数function的元素,重新返回一个新的迭代器。这个函数大概等价与下自定义的filter_self:
1 | def filter_self(function, iterable): |
- Filter_self函数接收一个function作为参数,满足条件的元素才得以保留。
下面根据实例看下这个函数,调用filter_self,筛选出满足指定身高的学生。条件:男生身高超过1.75,女生身高超过1.65.
1 | def filter_self(function, iterable): |
执行结果:
1 | /Users/lvjing/PycharmProjects/python_base_project/venv/bin/python /Users/lvjing/PycharmProjects/python_base_project/filter_sample_01.py |
解释下 height_condition 函数,其第一个参数是可迭代对象 iterable 中的一个元素,这是值得注意的。
以上是使用自定义过滤器,下面使用python内置的filter函数,也实现一遍学生身高筛选功能。
1 | students = [Student('xiaoming', 'male', 1.74), |
执行结果如下,与上面使用自定义过滤函数实现的结果相同。
1 | /Users/lvjing/PycharmProjects/python_base_project/venv/bin/python /Users/lvjing/PycharmProjects/python_base_project/filter_sample_01.py |
map(function,iterable,…)
map将function映射于iterable中的每一项,并返回一个新的迭代器。
如下,map函数实现每个元素加1:
1 | mylst = [1,3,2,4,1] |
map函数支持传入多个可迭代对象。当传入多个可迭代对象时,输出元素个数等于较短序列长度。
如下,传入两个列表,function就需要接收两个参数,取值分别对应第一、第二个列表中的元素。
找到同时满足第一个列表的元素为奇数,第二个列表对应位置的元素为偶数。
1 | xy = map(lambda x,y: x%2==1 and y%2==0, [1,3,2,4,1], [3,2,1,2]) |
map函数,还能实现向量级运算(两个数字列表相加)。
1 | lst1 = [1,2,3,4,5,6] |
也支持,向量长度不等的加法运算:
1 | lst1 = [1,2,3,4,5,6] |
reduce(function,iterable[,initializer])
提到map,就会想起reduce,前者生成映射关系,后者实现归约。
reduce函数位于functools模块中,使用前需要导入。reduce函数中第一个参数是函数function。function函数,参数个数必须为2,是可迭代对象iterable内的连续两项。
计算过程,从左侧到右侧,依次归约,直到最终为单个值并返回。
1 | from functools import reduce |
reversed(seq)
重新生成一个反向迭代器,对输入的序列实现反转。
1 | rev = reversed([1,4,2,3,1]) |
sorted(iterable,*,key=None,reverse=False)
实现对序列化对象的排序。
key参数和reverse参数必须为关键字参数,都是可省略。
1 | a = [1,4,2,3,1] |
如果可迭代对象的元素也是一个复合对象,如字典。依据为字典的键值,sorted的key函数就会被用到。
1 | a = [{'name':'xiaoming', 'age':20, 'gender':'male'}, {'name':'xiaohong', 'age':18, 'gender':'female'}, {'name':'xiaoli', 'age':19, 'gender':'male'}] |
排序的可视化图,如下所示:

迭代器
iter(object[,sentinel])
返回一个严格意义上的可迭代对象,其中,参数sentinel可有可无。
1 | lst = [1,3,5] |
it迭代结束后,在__next__时,触发StopIteration异常,即迭代器已经执行到最后。
下面的for和in结合,我们都比较熟悉,iterable为可迭代对象,依次迭代输出元素。
1 | for ele in iterable: |
对象iterable要想支持以上这类结构,需要满足什么条件呢?只要iterable对象支持可迭代协议,即自定义了__iter__函数,便都能配合for依次迭代输出其元素。
如下列子,TestIter类实现了迭代协议,__iter__函数。
1 | class TestIter(object): |
所以,对象t便能结合for,迭代输出元素。
1 | t = TestIter() |
执行结果
1 | /Users/lvjing/PycharmProjects/python_base_project/venv/bin/python /Users/lvjing/PycharmProjects/python_base_project/iter_sample_01.py |
next(iterator,[,default])
返回可迭代对象的下一个元素:
1 | it = iter([5,3,4,1]) |
当迭代到最后一个元素1时,再执行next,就会抛出StopIteration,迭代器终止运行。
案例:定制一个递减迭代器
编写一个迭代器,通过循环语句,对某个正整数,一次递减1,直到0.
实现类Descrease,集成与Iterator对象,重写两个方法:
__iter____next__
1 | from collections.abc import Iterator |
调用递减迭代器Decrease:
1 | descend_iter = Decrease(6) |
执行结果:
1 | /Users/lvjing/PycharmProjects/python_base_project/venv/bin/python /Users/lvjing/PycharmProjects/python_base_project/next_sample_01.py |
核心要点:
__next__名字不能变,实现定制的迭代逻辑- raise StopIteration:通过raise中断程序
enumerate(iterable, start=0)
enumerate是很有用的一个内置函数,尤其要用到列表索引时。
它返回可枚举对象,也是一个迭代器。
1 | s = ["a", "b", "c"] |
也可以手动执行next,依次输出一个tuple。
1 | enum = enumerate(s) |