迭代器(生成器)在Python中是一种很常用也很好用的数据结构,比起列表(list)来说,迭代器最大的优势就是延迟计算,按需使用,从而提高开发体验和运行效率。
现在我们知道生成器表达式是如何工作的,让我们再简要看一下 Pyhton 中另外一个重要的内置模块——itertools。它提供了可以创建高效循环的迭代器,提供了一些常用的迭代器,包括 count()、repeat()、chain()、groupBy()、tee()、product()、permutation()、combination()等。
itertools.accumulate
累加
>>> import itertools
>>> x = itertools.accumulate(range(5))
>>> print(list(x))
[0, 1, 3, 6, 10]
itertools.chain
连接多个列表
>>> x = itertools.chain(range(4),[1,2],[3,4])
>>> print(list(x))
[0, 1, 2, 3, 1, 2, 3, 4]
itertools.groupby
按照某个函数分组:功能非常强大,类似于pandas的groupby
>>> x = [{“a”:1},{“a”:2},{“a”:3}]
>>> x = itertools.groupby(x,lambda y: y[‘a’]<=2)
>>> for name,group in x:
… print(name,group)
True [{‘a’: 1}, {‘a’: 2}]
False [{‘a’: 3}]
itertools.permutations
排列,与下文的组合形成数学中的排列组合
>>> x = itertools.permutations(range(3),2)
>>> print(list(x))
[(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)]
itertools.combinations
组合:元素不重复
>>> x = itertools.combinations(range(3),2)
>>> print(list(x))
[(0, 1), (0, 2), (1, 2)]
**itertools.combinations_with_replacement**
组合:允许元素重复
>>> x = itertools.combinations_with_replacement(range(3),2)
>>> print(list(x))
[(0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2)]
itertools.compress
按照真值筛选
>>> x = itertools.compress(range(3),(True,False,False))
>>> print(list(x))
[0]
# 也支持其他类型的真值比如:0,1
>>> x = itertools.compress(range(3),(1,0,0))
>>> print(list(x))
[0]
itertools.islice
迭代器切片:参数分别是,迭代器,起始,终止,步长
>>> x = itertools.islice(range(20),0,11,3)
>>> print(list(x))
[0, 3, 6, 9]
itertools.count
计数器:指定起始和步长
>>> x = itertools.count(start=10,step=2)
>>> print(list(itertools.islice(x,0,5,1)))
[10, 12, 14, 16, 18]
注意:千万不要直接使用list(x)否则内存很可能炸了
itertools.filterfalse
保留:false对应的值,相对的是filter
>>> x = itertools.filterfalse(lambda x: x > 5, range(10))
>>> print(list(x))
[0, 1, 2, 3, 4, 5]
itertools.dropwhile
按照真值丢弃迭代器元素
>>> x = itertools.dropwhile(lambda x: x > 5, [8,6,4,2])
>>> print(list(x))
[4, 2]
itertools.takewhile
简单来说:与itertools.dropwhile相反
itertools.cycle
迭代器循环
>>> x = itertools.cycle([0,1,2])
>>> print(list(itertools.islice(x,0,5,2)))
[0, 2, 1]
itertools.product
以元组的形式,根据输入的可遍历对象生成笛卡尔积,与嵌套的for循环类似。
repeat是一个关键字参数,指定重复生成序列的次数
>>> a = (1,2,3)
>>> b = (‘a’,‘b’)
>>> x = itertools.product(a,b)
>>> print(list(x))
[(1, ‘a’), (1, ‘b’), (2, ‘a’), (2, ‘b’), (3, ‘a’), (3, ‘b’)]
itertools.repeat
重复元素一定次数
>>> x = itertools.repeat(1,4)
>>> print(list(x))
[1, 1, 1, 1]
itertools.starmap
类似于map
map:作用于迭代器的每一个元素
starmap:除了map功能,还可以作用于迭代器的不同元素
简单来说就是对于一个迭代器支持多元函数,map需要两个迭代器
>>> li =[(2, 3), (3, 1), (4, 6), (5, 3), (6, 5), (7, 2)]
>>> list(itertools.starmap(lambda x,y: x+y, li))
[5, 4, 10, 8, 11, 9]
>>> list(map(lambda x,y: x+y, li))
TypeError: <lambda>() missing 1 required positional argument: ‘y’
>>> list(map(lambda x , y : x ** y, [2,4,6],[3,2,1]))
[8, 16, 6]
itertools.tee
让一个迭代器被多次且完整的便利
这是一个爆炸内存的神奇QAQ
>>> x = itertools.tee(range(5),2)
>>> print([list(x) for x in x])
[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]
itertools.zip_longest
类似于zip,以长一点的迭代器为准
>>> x = itertools.zip_longest(range(3),range(5))
>>> print(list(x))
[(0, 0), (1, 1), (2, 2), (None, 3), (None, 4)]
>>> x = zip(range(3),range(5))
>>> print(list(x))
[(0, 0), (1, 1), (2, 2)]