itertools模块总结

itertools模块总结

python官方library中有一个itertools模块,官方是这么介绍的:

1
2
3
itertools — Functions creating iterators for efficient looping

The module standardizes a core set of fast, memory efficient tools that are useful by themselves or in combination. Together, they form an “iterator algebra” making it possible to construct specialized tools succinctly and efficiently in pure Python.

所以,itertools模块是一个创建快速高效迭代器的模块。

分类:

  • 无限型(Infinite Iterators)
  • 终止于最短输入序列的迭代器(Iterators terminating on the shortest input sequence)
  • 组合生成器 (Combinatoric generators)

无限迭代器

count(start, step)

  • 起始参数(start)默认值为0
  • 步长(step)默认值为1
  • 作用: 返回以start开头的均匀间隔step步长的值
1
2
3
4
from itertools import count
for item in count(1,10):
if item > 150: break
print(item,end=" ")

结果打印输出:1 11 21 31 41 51 61 71 81 91 101 111 121 131 141

如果没有截止条件,理论上会一直打印下去。

cycle(iterable)

  • iterable 为可迭代对象
  • 作用:保存迭代对象的每个元素的副本,无限的重复返回每个元素的副本
1
2
3
from itertools import cycle
for item in cycle('abcdef'):
print(item,end=" ")

结果打印输出:a b c d e f a b c d e……

repeat(elem[, times])

  • elem为述字符串,数字等对象
  • times为迭代次数,默认为无限次
  • 作用:按照指定的迭代次数times重复返回elem,如果不指定times,则为无限次
1
2
3
from itertools import repeat
for item in repeat('abcdef',4):
print(item,end=" ")

结果打印输出:abcdef abcdef abcdef abcdef

终止于最短输入序列的迭代器

accumulate(seq[,func])

  • seq为可迭代对象
  • func为累积执行的函数(默认为operator.add)
1
2
3
4
from itertools import accumulate
from operator import mul
for item in accumulate([1,2,3,4,5],mul):
print(item,end=" ")

结果打印输出:1 2 6 24 120

函数源码,划重点,理解迭代器和生成器的用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
def accumulate(iterable, func=operator.add):
'''Return running totals'''
# accumulate([1,2,3,4,5]) --> 1 3 6 10 15
# accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120
it = iter(iterable)
try:
total = next(it)
except StopIteration:
return
yield total
for element in it:
total = func(total, element)
yield total

chain(*iterables)

  • *iterables为一个或多个可迭代序列
  • 作用:返回所有可迭代序列
1
2
3
from itertools import chain
for item in chain('abcdef','123'):
print(item,end=" ")

结果打印输出:a b c d e f 1 2 3

compress(data, selectors)

  • data为数据对象
  • selectors为选择器(规则)
  • 作用:返回数据对象中对应规则为True的元素
1
2
3
from itertools import compress
for item in compress('abcdef',[1,0,1,1,0,0]):
print(item,end=" ")

结果打印输出:a c d

dropwhile(pred,seq)

  • pred为判断谓词
  • seq为可迭代序列
  • 作用:当pred为false时开始迭代
1
2
3
from itertools import dropwhile
for item in dropwhile(lambda x: x<5,[1,4,6,4,1]):
print(item,end=" ")

结果打印输出:6 4 1

takewhile(pred,seq)

  • pred为判断谓词
  • seq为可迭代对象
  • 作用:当pred为false时停止迭代
1
2
3
from itertools import takewhile
for item in takewhile(lambda x: x<5,[1,4,6,4,1]):
print(item,end=" ")

结果打印输出:1 4

filterfalse(pred,seq)

  • pred为判断谓词
  • seq为可迭代对象
  • 作用:当pred为false时迭代
1
2
3
4
#与filter相反
from itertools import filterfalse
for item in filterfalse(lambda x: x % 2,range(10)):
print(item,end=" ")

结果打印输出:0 2 4 6 8

groupby(iterable[, key])

  • iterable为可迭代对象
  • key分组的键值
  • 作用:创建一个迭代器,对iterable生成的连续项进行分组,在分组过程中会查找重复项。如果iterable在多次连续迭代中生成了同一项,则会定义一个组,如果将此函数应用一个分类列表,那么分组将定义该列表中的所有唯一项,key(如果已提供)是一个函数,应用于每一项,如果此函数存在返回值,该值将用于后续项而不是该项本身进行比较,此函数返回的迭代器生成元素(key, group),其中key是分组的键值,group是迭代器,生成组成该组的所有项。
  • 注意:当每次key函数返回的值变化时就产生一个新分组或break,所以需要先用key函数对对象进行排序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from itertools import groupby
def keyfunc(h):
if h > 180:
return 'tall'
elif h < 160:
return 'short'
else:
return 'middle'

data = [190,180,182,160,155,170,167,178]
data = sorted(data,key=keyfunc)
for k,g in groupby(data,key=keyfunc):
print(k)
print(list(g))

结果打印输出:

1
2
3
4
5
6
middle
[180, 160, 170, 167, 178]
short
[155]
tall
[190, 182]
1
2
3
4
5
from itertools import islice,groupby
for k, g in groupby('AAAABBBCCDAABBB'):
print(k,list(g))
# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D

结果打印输出:

1
2
3
4
5
6
A ['A', 'A', 'A', 'A']
B ['B', 'B', 'B']
C ['C', 'C']
D ['D']
A ['A', 'A']
B ['B', 'B', 'B']

islice(iterable, stop) / islice(iterable, start, stop[, step ])

  • iterable为可迭代对象
  • start、stop、step分别为起始位置、终止位置、和步长
  • 作用:创建一个迭代器,生成项的方式类似于切片返回值: iterable[start : stop : step],将跳过前start个项,迭代在stop所指定的位置停止,step指定用于跳过项的步幅。与切片不同,负值不会用于任何start,stop和step,如果省略了start,迭代将从0开始,如果省略了step,步幅将采用1.
1
2
3
4
5
6
7
from itertools import islice
for i in islice('ABCDEFG', 2):
print(i)
# islice('ABCDEFG', 2) --> A B
# islice('ABCDEFG', 2, 4) --> C D
# islice('ABCDEFG', 2, None) --> C D E F G
# islice('ABCDEFG', 0, None, 2) --> A C E G

starmap(func, seq)

  • func:计算函数
  • seq:需传递的参数
  • 作用:创建一个迭代器,生成值func(*item),其中item来自iterable,只有当iterable生成的项适用于这种调用函数的方式时,此函数才有效。
  • 注意:与map()starmap()的区别类似与function(a,b)function(*c)
1
2
3
4
from itertools import starmap
for i in starmap(pow,[(2,3),(3,2),(4,3)]):
print(i,end=" ")
#等价的map写法list(map(lambda x,y:pow(x,y),a,b))

结果打印输出:8 9 64

tee(iterable, n=2)

  • iterable为可迭代对象
  • n为需要的个数
  • 作用:从iterable创建n个独立的迭代器,创建的迭代器以n元组的形式返回,n的默认值为2,此函数适用于任何可迭代的对象,但是,为了克隆原始迭代器,生成的项会被缓存,并在所有新创建的迭代器中使用,一定要注意,不要在调用tee()之后使用原始迭代器iterable,否则缓存机制可能无法正确工作。
1
2
3
from itertools import tee
for ntee in tee("123456789",3):
print(list(ntee))

结果打印输出:

1
2
3
['1', '2', '3', '4', '5', '6', '7', '8', '9']
['1', '2', '3', '4', '5', '6', '7', '8', '9']
['1', '2', '3', '4', '5', '6', '7', '8', '9']

zip_longest(iter1,iter2, …)

  • iter1,iter2等为可迭代对象
  • 作用:与zip()相同,但是迭代过程会持续到所有输入迭代变量iter1,iter2等都耗尽为止,如果没有使用fillvalue关键字参数指定不同的值,则使用None来填充已经使用的迭代变量的值。
1
2
from itertools import zip_longest
print(list(zip_longest('abcd','12',fillvalue='-')))

结果打印输出:[(‘a’, ‘1’), (‘b’, ‘2’), (‘c’, ‘-‘), (‘d’, ‘-‘)]

组合生成器

product(iter1,iter2, … [repeat=1])

  • iter1,iter2等为可迭代对象
  • repeat是一个关键字参数,指定重复生成序列的次数
  • 作用:创建一个迭代器,生成表示item1,item2等中的项目的笛卡尔积的元组
1
2
3
4
from itertools import product
for ele in product('abcd','12'):
print(ele,end=' ')
# product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111

结果打印输出:(‘a’, ‘1’) (‘a’, ‘2’) (‘b’, ‘1’) (‘b’, ‘2’) (‘c’, ‘1’) (‘c’, ‘2’) (‘d’, ‘1’) (‘d’, ‘2’)

permutations(iterable [,r]):

  • iterable 为可迭代对象
  • r为长度
  • 作用:创建一个迭代器,返回iterable中所有长度为r的项目序列,如果省略了r,那么序列的长度与iterable中的项目数量相同
1
2
3
4
5
from itertools import permutations
for ele in permutations('abcd',r=2):
print(ele,end=' ')
# permutations(range(3)) --> 012 021 102 120 201 210
#The number of items returned is n! / (n-r)! when 0 <= r <= n or zero when r > n.

结果打印输出:(‘a’, ‘b’) (‘a’, ‘c’) (‘a’, ‘d’) (‘b’, ‘a’) (‘b’, ‘c’) (‘b’, ‘d’) (‘c’, ‘a’) (‘c’, ‘b’) (‘c’, ‘d’) (‘d’, ‘a’) (‘d’, ‘b’) (‘d’, ‘c’)

combinations(iterable, r)

  • iterable 为可迭代对象
  • r为长度
  • 作用:创建一个迭代器,返回iterable中所有长度为r的子序列,返回的子序列中的项按输入iterable中的顺序排序,元素不能重复出现
1
2
3
4
from itertools import combinations
for ele in combinations('abcd',r=2):
print(ele,end=' ')
#The number of items returned is n! / r! / (n-r)! when 0 <= r <= n or zero when r > n.

结果打印输出:(‘a’, ‘b’) (‘a’, ‘c’) (‘a’, ‘d’) (‘b’, ‘c’) (‘b’, ‘d’) (‘c’, ‘d’)

combinations_with_replacement(iterable, r)

  • iterable 为可迭代对象
  • r为长度
  • 作用:创建一个迭代器,返回iterable中所有长度为r的子序列,返回的子序列中的项按输入iterable中的顺序排序,元素可以重复出现
1
2
3
4
from itertools import combinations_with_replacement
for ele in combinations_with_replacement('abcd',r=2):
print(ele,end=' ')
#The number of items returned is (n+r-1)! / r! / (n-1)! when n > 0.

结果打印输出:(‘a’, ‘a’) (‘a’, ‘b’) (‘a’, ‘c’) (‘a’, ‘d’) (‘b’, ‘b’) (‘b’, ‘c’) (‘b’, ‘d’) (‘c’, ‘c’) (‘c’, ‘d’) (‘d’, ‘d’)