itertools模块包含创建高效迭代器的函数,这些函数的返回值不是list,而是iterator(可迭代对象),可以用各种方式对数据执行循环操作
count(), repeat(), cycle(), chain(), chain.from_iterable(), islice()
compress(), filterflase(), dropwhile(), takewhile(), accumulate(), groupby(), starmap(), tee(), zip_longest()
product(), permutations(), combinations(), combinations_with_replacement()
主要用于为模块中其他函数提供输入
count(start=0, step=1)可以从开始点产生无限数字序列,setp参数控制数字的间隔
for in itertools.cout(15,2):
if n<20:
pass
else:
break
repeat(object[, times])创建一个反复返回object的迭代器。times可指定返回的次数
>>> ns = itertools.repeat('A', 3)
>>> for n in ns:
... print(n)
...
>>> for n in range(7):
... print(next(itertools.repeat('yes ')))
...
cycle(iterable) 轮式迭代,重复再iterable上轮转
使迭代器从iterable返回元素并保存每个元素的副本。当iterable耗尽时,从保存的副本返回元素。重复无限。
可为负载平衡或资源分配创建轮式迭代
>>> res1=[]
>>> res2=[]
>>> res3=[]
>>> resources=itertools.cycle([res1,res2,res3])
>>> for n in range(30):
... res = next(resources)
... res.append(n)
...
>>> res1
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
>>> res2
[1, 4, 7, 10, 13, 16, 19, 22, 25, 28]
>>> res3
[2, 5, 8, 11, 14, 17, 20, 23, 26, 29]
chain(*iterable)将一组迭代对象串联起来,形成一个更大的迭代器
>>> for c in itertools.chain('ABC', 'XYZ'):
... print(c)
'A' 'B' 'C' 'X' 'Y'
chain.from_iterable(iterables) chain()的替代构造函数, iterables为生成iterable序列的迭代变量
# chain.from_iterable(['ABC', 'DEF']) --> A B C D E F
islice(iterable,start, stop[, step])
islice(iterable,stop)与切片类似,由于使用了生成器,再内存使用上更加高效
islice()不支持start,stop,step的负值。
# 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
接受输入数据并转化元素,或者以某种方式过滤内容
通常接受一个函数对象作为参数
compress(data, selectors) 创建迭代器,用于过滤data中的元素,只返回在selectors中具有对应元素为True的元素
# compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
selectors的布尔值,可以是可转化为布尔值的东西,可以为表达式
filterflase(data,selectors) 和compress类似,返回的是selectors对应为False的值
dropwhile(predicate, iterable) 创建迭代器,接受一个输入函数predicate和一个iterable,对于每个iterable中元素应用于函数
迭代器不会产生任何输出,直到predicate首次返回为假,因此它可能有一个冗长的启动时间。
# dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1
takewhile(predicate,iterable)与dropwhile类似,但是会返回元素直到predicate首次为False
# takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
accumulate(iterable[,func])创建的迭代对象返回iterable依次累加的值,或者其他通过func指定的二元函数的结果
func为接受两个参数的函数,第一个参数为上一次accumuulate生成的值,第二个为iterable的下一个值
iterable的元素是可以作为func参数的任何类型
如果输入iterable为空,则输出的迭代对象也为空
# accumulate([1,2,3,4,5]) --> 1 3 6 10 15
# accumulate([1,2,3,4,5],lambda x,y:x*y) -->1 2 6 24 120
groupby(iterable, key=None)创建一个迭代器,对iterable生成的连续项进行分组
返回的迭代器生成元素(key,group),key为分组的键值,group为迭代器,生成组成该组的所有项
如果iterable在多次连续迭代中生成了同一项,则会定义一个组
key为一个函数,应用于每一项,如果此函数存在返回值,则后续项与该值进行比较,而不是与该项本身比较
key默认为标识函数,并不更改元素
每当key函数的值发生变化时(通常需要使用相同的键函数对数据进行排序),它会生成一个断点或新的组。
这种行为不同于SQL的GROUP BY,它集合了公共元素,而不考虑它们的输入顺序。
# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
# [k for k, g in groupby('AAAABBBCCD')] --> A B C D
# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
通常需要使用相同的键函数对数据进行排序
data = sorted(data, key=keyfunc)
for k, g in groupby(data, keyfunc):
返回的group本身是一个迭代器,它与groupby()共享底层的可迭代器。
因为源是共享的,所以会导致先前的组不再可见,如果以后需要该数据,则应将其存储为列表:
groups = []
uniquekeys = []
data = sorted(data, key=keyfunc)
for k, g in groupby(data, keyfunc):
groups.append(list(g)) # Store group iterator as a list
uniquekeys.append(k)
starmap(func,iterable) 创建一个迭代器,生成值为func(*item),item来自iterable
# starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
与map()的区别在于function(a,b),function(*c),starmap的func参数函数可以接受任意个数参数
但是只有当iterable生成的项是用于这种调用函数的方式是,此函数才有效
tee(iterable, n=2) 从单个iterable中创建n个独立的迭代器。
创建的迭代器以n元组的形式返回
为了克隆原始迭代器,生成项会被还承诺,并在所有新创建的迭代器中使用
调用tee()拆分后,不要在任何其他地方使用试迭代器iterable
通常,如果一个迭代器在另一个迭代器开始之前使用大多数或所有数据,则不应使用tee(),而应该使用list()会更快
zip_longest(*iterables, fillvalue=None) 创建一个迭代器,聚合来自每个迭代器的元素。
如果迭代的长度不均匀,则缺少的值将被填充fillvalue。
迭代继续,直到最长可迭代被耗尽。
# zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
product(*iterables, repeat=1) 创建迭代器,生成iterables位置参数中项的笛卡尔积的元组,repeat指定重复生成序列的次数
大致等同于生成器表达式中的嵌套for循环,product(A, B)等同于( (x,y) for x in A for y in B)
# product('ABCD', 'xy')
('A','x') ('A','y') ...--> Ax Ay Bx By Cx Cy Dx Dy
# product(range(2), repeat=3)
(0,0,0) (0,0,1) ...--> 000 001 010 011 100 101 110 111
permutations(iterable, r=None) 创建迭代器,返回一个iterable中所有长度为r的项的序列
如果忽略r,则r默认为iterable的长度
元素根据它们的位置被视为唯一的而不是它们的值。
因此,如果输入元素是唯一的,则在每个排列中将不存在重复值。
# permutations('ABCD', 2)
('A','B') ('A', 'C') ... --> AB AC AD BA BC BD CA CB CD DA DB DC
# permutations(range(3)) --> 012 021 102 120 201 210
combinations(iterable, r) 与permutations()类似,但是返回的子序列中的项按照iterable中的顺序排列
# combinations('ABCD', 2)
('A','B') ('A','C') ...--> AB AC AD BC BD CD
# combinations(range(4), 3)
(0,1,2) (0,1,3) ...--> 012 013 023 123
combinations_with_replacement(iterable,r) 与combinations()类似,但是允许单个元素重复一次以上
# combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC