filter(function, iterable)
过滤器,过滤掉不满足函数 function 的元素,重新返回一个新的迭代器。
可以如下自定义过滤器函数,实现针对男女性身高筛选:
# filter过滤器 def filter_self(function, iterable): return iter([ item for item in iterable if function(item)]) class Student(): def __init__(self,name,sex, height): self.name = name self.sex = sex self.height = height def height_condition(stu): if stu.sex == 'male': return stu.height > 1.75 else: return stu.height > 1.65 students = [Student('xiaoming','male',1.74), Student('xiaohong','female',1.68), Student('xiaoli','male',1.80)] students_satisfy = filter_self(height_condition,students) for stu in students_satisfy: print(stu.name) type(students_satisfy) output: xiaohong xiaoli list_iterator
python中内置的函数filter(func, iter)如下:
students_satisfy = filter(height_condition,students) for stu in students_satisfy: print(stu.name) type(students_satisfy) output: xiaohong xiaoli filter
- type(students_satisfy) 返回的略有不同
map(function, iterable, ...)
在c++中,map用于生成哈希表,而在python中,map将function 映射于 iterable 中的每一项,并返回一个新的迭代器。
- 就是做一次映射,将映射结果以一个新的迭代器返回。
- map 函数支持传入多个可迭代对象。出元素个数等于较短序列长度。
map 函数实现f(x) = x + 1:
# map 映射函数 lst = [1,2,3,4,5,6,8] ret = map(lambda x:x+1,lst) print(ret) print(list(ret)) output: <map object at 0x6fffe0f9390> [2, 3, 4, 5, 6, 7, 9]
观察到定义中允许传入几个可迭代对象,表示function需要用到的几个参数,这时输出元素个数等于较短序列长度。
map函数实现f(x,y) = x*y:
ret = map(lambda x,y:x*y, [1,2,3,4,5,6,8],[5,4,3,2,1]) print(ret) print(list(ret)) output: <map object at 0x6fffe0f9a20> [5, 8, 9, 8, 5]
p.s. 多记忆lambda的使用方法!
例如借助 map 函数,还能实现向量级运算,即使长度不相等也可以,输出短的size的映射结果:
lst1 = [1,2,3,4,5,6,8] lst2 = [8,5,2,9,3,1,7] def vector_add(x,y): return list(map(lambda x,y:x+y,x,y)) vector_add(lst1,lst2) output: [9, 7, 5, 13, 8, 7, 15]
reduce(function, iterable[, initializer])
不同于map实现映射功能,reduce实现 规约。
- reduce 函数位于 functools 模块中,使用前需要先导入。
from functools import reduce
- function函数的参数必须为2,是可迭代对象 iterable 内的连续两项。
- 计算过程,从左侧到右侧,依次归约,直到最终为单个值并返回。
例如计算1+2+...+19:
reduce(lambda x,y:x+y,list(range(0,20)))
output:
190
reversed(seq)
重新生成一个反向迭代器,对输入的序列实现反转。
ret = reversed([1,2,3,4,5,6,8])
list(ret)
output:
[8, 6, 5, 4, 3, 2, 1]
sorted(iterable, *, key=None, reverse=False)
实现对序列化对象的排序,重要的是依据什么来排序!key=None, reverse=False 就此而来
key 参数和 reverse 参数必须为关键字参数,都可省略。
lst = [1,2,3,4,5,6,8,6,1] sorted(lst,reverse=True) output: [8, 6, 6, 5, 4, 3, 2, 1, 1]
如果序列化对象的元素是一个字典,这时候key关键字就用得上了:
a = [{'name':'xiaoming','age':20,'gender':'male'}, {'name':'xiaohong','age':18,'gender':'female'}, {'name':'xiaoli','age':19,'gender':'male'}] b = sorted(a,key=lambda x: x['age'],reverse=False) b output: [{'name': 'xiaohong', 'age': 18, 'gender': 'female'}, {'name': 'xiaoli', 'age': 19, 'gender': 'male'}, {'name': 'xiaoming', 'age': 20, 'gender': 'male'}]
以上例子根据关键字‘age’进行排序,正序排序。
iter(object[, sentinel])
返回一个严格意义上的可迭代对象,其中,参数 sentinel 可省略。
# iter迭代器 lst = [1,23,4,5,6,8,] it = iter(lst) print(type(it)) print(it)#严格的迭代器不能用print()函数打出来 print(it.__next__()) print(it.__next__()) print(it.__next__()) print(it.__next__()) print(it.__next__()) print(it.__next__()) print(it.__next__()) output: <class 'list_iterator'> <list_iterator object at 0x6fffdf89470> 1 23 4 5 6 8 --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-25-794a6047bc88> in <module>() 11 print(it.__next__()) 12 print(it.__next__()) ---> 13 print(it.__next__()) StopIteration:
it 迭代结束后,在 __next__ 时,触发 StopIteration 异常,即迭代器已经执行到最后。可以捕获来提升迭代器已经执行到最后。可以用for _ in it: 来提取iterator中的元素:
# iter迭代器 lst = [1,23,4,5,6,8,] it = iter(lst) print(type(it)) print(it)#严格的迭代器不能用print()函数打出来 for _ in it: print(_) output: <class 'list_iterator'> <list_iterator object at 0x6fffe3dc5f8> 1 23 4 5 6 8
对象 it 要想支持以上这类结构,需要满足什么条件?
只要 iterable 对象支持可迭代协议,即自定义了 __iter__ 函数,便都能配合 for 依次迭代输出其元素。
下面将自定义对象的__iter__ 函数:
class myIter(object): def __init__(self): self._lst = [1,2,3,4,5,6,8,5,1,13] #支持迭代协议(即定义有 __iter__() 函数) def __iter__(self): print ("__iter__ is called!!") return iter(self._lst) ret = myIter() for _ in ret: print(_) output: __iter__ is called!! 1 2 3 4 5 6 8 5 1 13
next(iterator,[, default])
返回可迭代对象的下一个元素。和上述it.__next__()效果一样,当迭代到最后一个元素后再执行一次next()函数,就会抛出StopIteration错误。
it = iter([5,3,4,1]) print(next(it)) print(next(it)) print(next(it)) print(next(it)) print(next(it)) output: 5 3 4 1 --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-32-e71d85ab85d9> in <module>() 4 print(next(it)) 5 print(next(it)) ----> 6 print(next(it)) StopIteration:
例子,重新定义__iter__() 和 __next__()方法,达到通过循环语句,对某个正整数,依次递减 1,直到 0功能:
- __next__ 名字不能变,实现定制的迭代逻辑
- raise StopIteration:通过 raise 中断程序。
from collections.abc import Iterator class Decrease(Iterator): def __init__(self, init): self.init = init def __iter__(self): return self def __next__(self): while 0 < self.init: self.init -= 1 return self.init raise StopIteration descend_iter = Decrease(10) for i in descend_iter: print(i) output: 9 8 7 6 5 4 3 2 1 0
enumerate(iterable, start=0)
返回可枚举对象,也是一个迭代器。
# enumerate返回可枚举对象,是迭代器 lst = ['a','s','d','748'] for i,value in enumerate(lst): print(i,value) print(type(enumerate(lst))) output: 0 a 1 s 2 d 3 748 <class 'enumerate'>