itertools标准库
Python的一大特性是具有一个强大的标准库,让我们在很多时候可以采用“拿来主义”直接使用标准库完成一些功能,并且标准库的实现总是最优的实现。本系列的上篇文章中介绍了Python中的迭代器,本篇来详细看一下标准库都提供了哪些便捷的迭代器工具。(官方文档地址:https://docs.python.org/3/library/itertools.html)
约定
所有代码段默认都有;
表示在打印后不换行;
所有功能均返回迭代器,为了便于查看内容,部分返回值转为;
无限迭代器
count
迭代器用于从某个位置开始计数,我们可以利用参数来指定起始位置和步长,并且没有终止条件:
fromitertoolsimport*
# 本文代码默认认为执行了
# from itertools import *
counter=count(5,2)
print(counter.__next__())
# 5
print(counter.__next__())
# 7
print(counter.__next__())
# 9
# ...
cycle
可以循环遍历一个可迭代对象的每一个元素,并且遍历结束后会从头开始进行下一轮遍历,如此往复。
repeat
顾名思义,可以将一个对象重复次(可选):
repeater=repeat(5,5)
print(list(repeater))
# [5, 5, 5, 5, 5]
有限迭代器
accumulate
累加操作:
print(list(accumulate(
[1,2,3,4]
)))
# [1, 3, 6, 10]
和十分相似(在这里→点我传送),只不过的是一个最终结果,就是的最后一项,而返回每一次叠加的中间值的迭代器。也允许自定义操作函数:
fromoperatorimportmul
# 乘法
print(list(accumulate(
[1,2,3,4],
mul
)))
# [1, 2, 6, 24]
chain
将多个可迭代对象链接起来,组成一个完整的迭代器:
a= [1,2,3]
b='ABC'
c=repeat('d',3)
chains=chain(a,b,c)
foreleinchains:
print(ele,end='')
# 123ABCddd
chain.from_iterable
它是类的一个类方法。它实现的功能与类似,只不过它接收一个可迭代对象,将这个对象的每一个元素链接起来:
d= [a,b,'efg']# a, b在上面
chains=chain.from_iterable(d)
foreleinchains:
print(ele,end='')
# 123ABCefg
compress
字面意思是压缩,实际上它是将一个可迭代对象按照一个选择器的真假来筛选值,有点类似于,只是适用范围更精确:
data='ABCDEFG'
selector= [,1,1,1,,,1]
compressed=compress(
data,
selector
)
print(list(compressed))
# ['B', 'C', 'D', 'G']
# 只有selector中为True的位置
# 被保留了下来
它等价于这样的写法:
fromoperatorimportitemgetter
filtered=map(
itemgetter(1),
filter(
lambdax:selector[x[]],
enumerate(data)
)
)
print(list(filtered))
# ['B', 'C', 'D', 'G']
或是利用推导式实现:
compred= [
xfori,xinenumerate(data)
ifselector[i]
]
print(compred)
# ['B', 'C', 'D', 'G']
# 下面是官方写法:
compred= [
dford,sinzip(
data,
selector
)ifs
]
print(compred)
# ['B', 'C', 'D', 'G']
但是,推导式返回的直接是列表对象,不是迭代器。
dropwhile
它接收两个参数,和。它输出当首次为之后的迭代器,来看个例子:
takewhile
它是的逆向操作,当条件为后立刻停止迭代:
falsefilter
这个在这里(→
点我传送
)讲过了~
groupby
是一个十分强大的迭代器类,它可以依照用户自定的方式将一个可迭代对象中的内容进行分组,并输出分组的标准和被分出的组的内容的迭代器。需要注意的是,当每次函数值改变时,都会产生一个新的组,而不管这个组是否在之前出现过了。所以很多时候,在使用之前需要给可迭代对象排序。例如,将一个字典按照值来将键分组:
importoperator
dic= {
'a':1,
'b':2,
'c':3,
'd':1,
'e':2,
'f':1,
'g':2,
'h':3
}
forval,groupingroupby(
dic.items(),
operator.itemgetter(1)
):
print(val,list(group))
# 1 [('a', 1)]
# 2 [('b', 2)]
# 3 [('c', 3)]
# 1 [('f', 1)]
# 3 [('h', 3)]
# 2 [('g', 2)]
# 1 [('d', 1)]
# 2 [('e', 2)]
# 先按value排序
sort_dic=sorted(
dic.items(),
key=operator.itemgetter(1)
)
# 再groupby
forval,groupingroupby(
sort_dic,
operator.itemgetter(1)
):
print(val,list(group))
# 1 [('a', 1), ('f', 1), ('d', 1)]
# 2 [('b', 2), ('e', 2), ('g', 2)]
# 3 [('c', 3), ('h', 3)]
islice
是切片操作的迭代器版本。可以接收的参数依次为:可迭代对象,起始位置(默认为0),终止位置(默认到结束),步长(可选)。后三个参数不可为负(不同于普通切片):
seq='ABCDEFGH'
# 普通切片
print(seq[:4])
# ABCD
print(list(islice(seq,4)))
# ['A', 'B', 'C', 'D']
print(str(islice(seq,3,None)))
# ['D', 'E', 'F', 'G', 'H']
starmap
它在的基础上多了个,意思是将一个可迭代对象的每个元素通过进行拆解后,传递给一个函数作为参数,并输出一个函数执行的迭代器:
fromoperatorimportadd
seq= [(1,2), (3,4), (5,6)]
new_iter=starmap(add,seq)
print(list(new_iter))
# [3, 7, 11]
它很类似,区别在于映射函数的参数不止一个,且已经被“打包”进了一个可迭代对象中。它的等价写法是显示地将参数利用星号表达式拆解出来:
new_iter=map(
lambdax:add(*x),
seq
)
print(list(new_iter))
# [3, 7, 11]
tee
它可以将一个可迭代对象“复制”出个独立的迭代器:
seq= [1,2,3,4]
seqiter=iter(seq)
seq1,seq2,seq3=tee(seqiter,3)
foreleinseq1:
print(ele,end='')
print()
# 1234
foreleinseq2:
print(ele,end='')
print()
# 1234
foreleinseq3:
print(ele,end='')
print()
# 1234
foreleinseqiter:
print(ele,end='')
#
可以看到,如果给传入一个迭代器,那么所有的迭代器(包括原始迭代器)最多可以迭代次。
zip_longest
在这里(→点我传送)讲过了。
组合学迭代器
product
顾名思义,产生两个可迭代对象的笛卡尔积的结果:
frompprintimportpprint
a='ABC'
b= [1,2,3]
pab=product(a,b)
pprint(list(pab))
# [('A', 1),
# ('A', 2),
# ('A', 3),
# ('B', 1),
# ('B', 2),
# ('B', 3),
# ('C', 1),
# ('C', 2),
# ('C', 3)]
permutations
产生一个可迭代对象元素的全排列:
a='ABC'
pera=permutations(a)
pprint(list(pera))
# [('A', 'B', 'C'),
# ('A', 'C', 'B'),
# ('B', 'A', 'C'),
# ('B', 'C', 'A'),
# ('C', 'A', 'B'),
# ('C', 'B', 'A')]
combinations
产生一个可迭代对象的长度的子序列的组合:
a='ABCD'
r=2
coma=combinations(a,r)
pprint(list(coma))
# [('A', 'B'),
# ('A', 'C'),
# ('A', 'D'),
# ('B', 'C'),
# ('B', 'D'),
# ('C', 'D')]
上面这个组合操作不会将元素本身的组合计算到里面。如果想要包括自身的组合,需要使用下面的方法:
combinations_with_replacement
a='ABCD'
r=2
coma=combinations_with_replacement(
a,
r
)
pprint(list(coma))
# [('A', 'A'),
# ('A', 'B'),
# ('A', 'C'),
# ('A', 'D'),
# ('B', 'B'),
# ('B', 'C'),
# ('B', 'D'),
# ('C', 'C'),
# ('C', 'D'),
# ('D', 'D')]
友情链接: https://vonalex.github.io/
欢迎关注 它不只是Python
领取专属 10元无门槛券
私享最新 技术干货