Python标准库中的生成器函数
一、用于过滤的生成器函数
- 从输入的可迭代对象中产出元素的子集,而不修改元素本身
import itertools l1 = [1,2,3,4,5] l2 = [True,False,True,False,True] def predict(k): return l2[k-1] # compress(it,selector_it)并行处理两个可迭代对象, # 如果selector_it中的元素是真值,产出it中对应的元素 # 输出: 1,3,5 for i in itertools.compress(l1,l2): print(i) # takewhile(predicate,it)当predicate返回真值时产出对应的元素,然后停止不再继续检查 # 输出:1 for i in itertools.takewhile(predict,l1): print(i) # dropwhile(predicate,it)处理it,跳过predicate计算结果为True的元素后, # 不再进一步检查,产出剩下的元素 # 输出:2,3,4,5 for i in itertools.dropwhile(predict,l1): print(i) # filter(predicate,it)把it中的各个元素传给predicate, # 如果predicate(item)返回真,则产出 # 输出:1,3,5 for i in filter(predict,l1): print(i) # filterfalse(predicate,it)与filter类似,逻辑相反 # 输出:2,4 for i in itertools.filterfalse(predict,l1): print(i) # islice(it,stop)作用类似于s[:stop] # 输出:1,2,3 for i in itertools.islice(l1,3): print(i) # islice(it,start,stop,step=1)作用类似于s[start:stop:step] # 输出:1,3,5 for i in itertools.islice(l1,0,5,2): print(i)
二、用于映射的生成器函数
- 在输入的可迭代对象中的各个元素上做计算,然后返回结果。
import itertools import operator l1 = [1,2,3,4,5] # accumulate(it)产出累计总和 # 输出:1,36,10,15 for i in itertools.accumulate(l1): print(i) def sub(a,b): return a-b # accumulate(it,func)把前两个元素传给func, # 然后把计算结果和下一个元素传给它,以此类推 # 输出:1,1,1,1,1 for i in itertools.accumulate(l1,min): print(i) # enumerate(it,start=0)产出由两个元素组成的元组,结构是(index,item) # 其中index从start开始计数,item从it中获取 # 输出:(0,1),(1, 2),(2, 3),(3, 4),(4, 5) for i in enumerate(l1,0): print(i) def double(k): return k*2 # map(func,it)把it中的各个元素传给func,产出结果 # 输出:2,4,6,8,10 for i in map(double,l1): print(i) def join(*a): return '_'.join(a) l1 = ['a','b','c'] l2 = ['a','b','c'] l3 = ['a','b','c'] # map(func,it1,it2,...)如果有多个可迭代对象, # 那么func必须能接受多个参数,并行处理各个可迭代对象 # 输出:a_a_a,b_b_b,c_c_c for i in map(join,l1,l2,l3): print(i) # starmap(func,it)把it中各个元素传给func,产出结果 # 这个函数要求it中的元素也是可迭代对象,func的参数类型为*var # 输出:a,bb,ccc for i in itertools.starmap(operator.mul,enumerate(l1,1)): print(i)
三、用于合并的生成器函数
- 从输入的多个可迭代对象中产出元素
import itertools l1 = [1,2,3,4] l2 = [6,7,8,9,10] # itertools.chain(it1,...,itN) 返回一个生成器 # 先产出it1中所有元素,然后产出it2中所有元素,以此类推 l3 = list(itertools.chain(l1,l2)) # l3: [1, 2, 3, 4, 6, 7, 8, 9, 10] print('l3:',l3) # zip(it1,...,itN):返回一个生成器 # 并行从输入的各个可迭代对象中获取元素,产出由N个元素组成的元组 # 只要有一个可迭代对象到头了就停止,不报错 l4 = list(zip(l1,l2)) # l4: [(1, 6), (2, 7), (3, 8), (4, 9)] print('l4:',l4) # itertools.chain.from_iterable(it) 返回一个生成器 # 参数it是一个由可迭代对象组成的可迭代对象,函数将这些对象拆分后产出 l5 = list(itertools.chain.from_iterable(l4)) # l5: [1, 6, 2, 7, 3, 8, 4, 9] print('l5:',l5) # 但只会拆分一层,不会递归拆分 # l6: [((1, 6), (1, 6)), ((2, 7), (2, 7)), ((3, 8), (3, 8)), ((4, 9), (4, 9))] l6 = list(zip(l4,l4)) print('l6:',l6) # l7:[(1, 6), (1, 6), (2, 7), (2, 7), (3, 8), (3, 8), (4, 9), (4, 9)] l7 = list(itertools.chain.from_iterable(l6)) print('l7:',l7) l8 = [1,2] l9 = [3,4] l10 = [5,6] # itertools.product(it1,...,itN) 返回一个生成器 # 计算笛卡尔积,从输入的各个可迭代对象中获取元素,合并成由N个元素组成的元组 l11 = list(itertools.product(l8,l9,l10)) # l11:[(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6)] print('l11:',l11) # itertools.zip_longest(it1,...,itN,fillvalue=None) 返回一个生成器 # 并行从输入的各个可迭代对象中获取元素,产出由N个元素组成的元组 # 等到最长的可迭代对象到头后才停止,空缺的值用fillvalue填充 l12 = list(itertools.zip_longest(l1,l2,fillvalue='fill')) # l12: [(1, 6), (2, 7), (3, 8), (4, 9), ('fill', 10)] print('l12:',l12)
四、用于扩展输入的可迭代对象的生成器
import itertools l1 = [1,2,3,4,5] # itertools.combinations(it,out_len) 返回一个生成器 # 把it中out_len个元素的组合以元组的形式输出 l2 = list(itertools.combinations(l1,2)) # l2: [(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)] print('l2:',l2) # itertools.combinations_with_replacement(it,out_len) 返回一个生成器 # 把it中out_len个元素的组合以元组的形式输出,包括相同元素 l3 = list(itertools.combinations_with_replacement(l1,2)) # l3: [(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 2), (2, 3), (2, 4), (2, 5), (3, 3), # (3, 4), (3, 5), (4, 4), (4, 5), (5, 5)] print('l3:',l3) # itertools.count(start=0,step=1) 返回一个生成器 # 从start开始不断产生数字,按step指定的步幅增加 l4 = list(itertools.islice(itertools.count(start=2,step=2),5)) # l4:[2, 4, 6, 8, 10] print('l4:',l4) # itertools.cycle(it) 返回一个生成器 # 从it中拿出各个元素的副本,按顺序重复不断地产出各个元素 l5 = list(itertools.islice(itertools.cycle('ABC'),10)) # l5: ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A'] print('l5:',l5) # itertools.permutations(it,out_len=None) 返回一个生成器 # 生成out_len个it产出的元素的排列 l6 = list(itertools.permutations('ABC')) # l6: [('A', 'B', 'C'), ('A', 'C', 'B'), ('B', 'A', 'C'), ('B', 'C', 'A'), ('C', 'A', 'B'), ('C', 'B', 'A')] print('l6:',l6) # itertools.repeat(item,[times]) 返回一个生成器 # 重复不断产出指定元素,除非提供times指定次数 l7 = list(itertools.repeat(7,5)) # l7: [7, 7, 7, 7, 7] print('l7:',l7)
五、用于重新排列元素的生成器函数
- 以某种方式进行重排列
import itertools # itertools.groupby(it,key=None) 返回一个迭代器 # 产出由两个元素组成的元素,形式为(key,group),其中key是分组标准, # group是生成器,用于产生分组中的元素 # 使用这个函数之前必须对输入的可迭代对象使用分组标准进行排序,否则输出会混乱 for char, group in itertools.groupby('LLLLAAGGG'): # L -> ['L', 'L', 'L', 'L'] # A -> ['A', 'A'] # G -> ['G', 'G', 'G'] print(char,'->',list(group)) animals = ['duck','eagle','rat','giraffe','bear','bat','dolphin','shark','lion'] animals.sort(key=len) for length,group in itertools.groupby(animals,len): # 3 -> ['rat', 'bat'] # 4 -> ['duck', 'bear', 'lion'] # 5 -> ['eagle', 'shark'] # 7 -> ['giraffe', 'dolphin'] print(length,'->',list(group)) # reversed(seq) 从后向前,倒序产出seq中的元素 # seq必须是序列,或者是实现了__reversed__特殊方法的对象 for length,group in itertools.groupby(reversed(animals),len): # 7 -> ['dolphin', 'giraffe'] # 5 -> ['shark', 'eagle'] # 4 -> ['lion', 'bear', 'duck'] # 3 -> ['bat', 'rat'] print(length,'->',list(group)) # itertools.tee(it,n=2) 返回一个迭代器 # 产生多个迭代器,每个迭代器都和输入的可迭代对象一致 g1,g2,g3 = itertools.tee('ABC',3) l1 = list(g1) l2 = list(g2) l3 = list(g3) # l1: ['A', 'B', 'C'] print('l1:',l1) # l2: ['A', 'B', 'C'] print('l2:',l2) # l3: ['A', 'B', 'C'] print('l3:',l3)