python itertools模块
1、创建属于自己的迭代器,实现遍历
2、快速&节约内存
无限迭代器:
count
cycle
repeat
count返回一系列值,以start参数开始,也可以接受step参数
无step方式:
from itertools import count
for i in count(10):
if i>20:
break
else:
print(i)
结果为:10 11 12 13 14 15 16 17 18 19 20
有step方式:
from itertools import count,islice:
for i in islice(count(10),10):
print(i)
结果为:10 11 12 13 14 15 16 17 18 19
解析:count从10开始,迭代10次后停止
cycle迭代器可实现在序列上创建无限循环的迭代器
用计数的方式实现有限迭代:
from itertools import cycle
count =0
for item in cycle("ABCDEFG"):
if count >20:
break
else:
print(item)
count+=1
结果为:A B C D E F G A B C D E F G A B C D E F G
解析:cycle("ABCDEFG")会生成一个由"A" "B" "C" "D" "E" "F" "G"组成的无限循环迭代器,可实现遍历
用python内置next()函数实现遍历迭代
from itertools import cycle
list1=["A","B","C","D","E","F","G"]
iterator=cycle(list1)
for i in range(20):
print(next(iterator))
结果为:A B C D E F G A B C D E F G A B C D E F
解析:cycle("ABCDEFG")会生成一个由"A" "B" "C" "D" "E" "F" "G"组成的无限循环迭代器,
每次调用next()函数会返回迭代器中的下一个值
repeat迭代器返回同一个对象,如不设定次数会无限迭代
指定迭代次数:
from itertools import repeat
iterator=repeat("txd",5)
for i in range(6):
print(next(iterator))
结果:txd txd txd txd txd
第六次执行迭代next()方法时报错:
Traceback (most recent call last):
File "D:\unitest\exercise\排序.py", line 4, in <module>
print(next(iterator))
StopIteration
解析:由于指定了迭代次数为5,循环执行到第6次时会报错
不指定迭代次数:
from itertools import repeat
iterator=repeat("txd")
for i in range(20):
print(next(iterator))
结果:txd txd txd txd txd txd txd txd txd txd txd txd txd txd txd txd txd txd txd txd txd txd txd txd txd
有限迭代器
accumulate迭代器返回累加之和或两个函数的累计结果
返回迭代器每对象被累加之和:
from itertools import accumulate
print(list(accumulate(range(20))))
结果:[0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190]
解析:第一个是0,第二个是0+1,第三个是1+2,等等;用内置的list方法,为了可读性强,否则仅仅打印出迭代器对象
返回迭代器对象被operator.mul函数相乘之积:
from itertools import accumulate
import operator
print(list(accumulate(range(1,20),operator.mul)))
结果:[1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6402373705728000, 121645100408832000]
解析:第一个是1,第二个是1*2,第三个是2*3,等等;用内置的list方法,为了可读性强,否则仅仅打印出迭代器对象
chain迭代器将一系列可迭代对象平铺为一个长的可迭代对象
使用chain完成迭代器合并:
from itertools import chain
list1=[1,2,3,4,5]
list2=['a','b','c','d','e']
list3=['ls','cd','mv','/home','/usr']
fn_list=list(chain(list1,list2,list3))
print(fn_list)
结果:[1, 2, 3, 4, 5, 'a', 'b', 'c', 'd', 'e', 'ls', 'cd', 'mv', '/home', '/usr']
list1地址为:1921345868416;fn_list地址为1921348731392
解析:将可迭代对象传入chain迭代器中;用内置的list方法,为了可读性强,否则仅仅打印出迭代器对象
另一种方式,直接使用列表的添加:
list1=[1,2,3,4,5]
list2=['a','b','c','d','e']
list3=['ls','cd','mv','/home','/usr']
fn_list=list1+list2+list3
print(fn_list)
print("list1地址为:{0};fn_list地址为{1}".format(id(list1),id(list2)))
结果:[1, 2, 3, 4, 5, 'a', 'b', 'c', 'd', 'e', 'ls', 'cd', 'mv', '/home', '/usr']
list1地址为:1921348872640;fn_list地址为1921345868416
使用chain里from_iterable()方法,与chain不同的是,需要传递一个嵌套的列表
from itertools import chain
list1 = [1, 2, 3, 4, 5]
list2 = ['a', 'b', 'c', 'd', 'e']
list3 = ['ls', 'cd', 'mv', '/home', '/usr']
print(list(chain.from_iterable(list1,list2,list3)))
结果:
Traceback (most recent call last):
File "D:\unitest\exercise\排序.py", line 6, in <module>
print(chain.from_iterable(list1,list2,list3))
TypeError: chain.from_iterable() takes exactly one argument (3 given)
正确方式为:
from itertools import chain
list1 = [1, 2, 3, 4, 5]
list2 = ['a', 'b', 'c', 'd', 'e']
list3 = ['ls', 'cd', 'mv', '/home', '/usr']
print(list(chain.from_iterable([list1,list2,list3])))
结果为:[1, 2, 3, 4, 5, 'a', 'b', 'c', 'd', 'e', 'ls', 'cd', 'mv', '/home', '/usr']
compress子模块可实现迭代器过滤,传入两个迭代器,通过第二个迭代器的布尔表达式判断进行筛选
from itertools import compress
list1=[1,2,3,4,5,5]
list2=[True,False,False,True]
print(list(compress(list1,list2)))
结果:[1, 4]
dropwhile
from itertools import dropwhile
list1=[1,2,3,4,5,6,7,8,9,10,9,8,7]
print(list(dropwhile(lambda x:x < 10,list1)))
结果:[10, 9, 8, 7]
from itertools import dropwhile
list1=[1,2,3,4,5,6,7,8,9,10,11,10,9,8,7]
print(list(dropwhile(lambda x:x > 10,list1)))
结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 10, 9, 8, 7]
解析:dropwhile内部判断一旦为false,则获得该迭代对象及它之后的元素
talkwhile 与dropwhile 刚好相反,遇到条件为False时,忽略可迭代对象中剩余的元素
filterfalse 只返回判断为false的值
from itertools import filterfalse
list1=[1,2,3,4,5,6,7,8,9,10,11,20,21,22,23,23,35,562,10,9,8,7]
print(list(filterfalse(lambda x:x > 10,list1)))
结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 9, 8, 7]
groupby 迭代器返回迭代器对象中连续的keys和groups
传入groupby 的为排序后的迭代器
from itertools import groupby
vehicles =[('Ford','Taurus'),('Dodge','Durango'),('Chevrolet','Cobalt'),('Ford','F150'),('Dodge','Charger'),('Ford','GT')]
sorted_vehicles =sorted(vehicles)
for key ,group in groupby(sorted_vehicles,lambda make:make[0]):
for make ,model in group:
print("{model} is made by {make}".format(model=model,make=make))
print("------ End of Group-----")
结果:
Cobalt is made by Chevrolet
***** End of Group *****
Charger is made by Dodge
Durango is made by Dodge
***** End of Group *****
F150 is made by Ford
GT is made by Ford
Taurus is made by Ford
***** End of Group *****
传入groupby的非排序后的迭代器:
from itertools import groupby
vehicles =[('Ford','Taurus'),('Dodge','Durango'),('Chevrolet','Cobalt'),('Ford','F150'),('Dodge','Charger'),('Ford','GT')]
for key ,group in groupby(vehicles,lambda make:make[0]):
for make ,model in group:
print("{model} is made by {make}".format(model=model,make=make))
print("------ End of Group-----")
结果为:
Taurus is made by Ford
------ End of Group-----
Durango is made by Dodge
------ End of Group-----
Cobalt is made by Chevrolet
------ End of Group-----
F150 is made by Ford
------ End of Group-----
Charger is made by Dodge
------ End of Group-----
GT is made by Ford
------ End of Group-----
islice从迭代对象中返回选择元素的迭代器
itertools.islice(iterable,stop)方式
from itertools import islice
print(list(islice([1,2,3,4,5,6,7,8],4)))
结果:[1, 2, 3, 4]
itertools.islice(iterable,start,stop,[,step])方式
from itertools import islice
print(list(islice([1,2,3,4,5,6,7,8,9],4,9)))
结果:[5, 6, 7, 8, 9]
starmap会创建一个新迭代器,与map()区别是:map()传入的函数是function(*c),starmap()传入的是function(a,b)
from itertools import starmap
def add_f(a,b):
return a+b
for item in starmap(add_f,[(1,3),(5,8),(9,100)]):
print(item)
结果:
4
13
109
tee 实现从一个迭代器中创建多个迭代器
from itertools import tee
list1=[1,2,3,4,5,6]
iter1,iter2=tee(list1)
print(list(iter1))
print(list(iter2))
结果:
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]
zip_longest 将两个迭代对象打包在一起,如果可迭代对象长度不同,可以传入fillvalue
from itertools import zip_longest
A=['a','b','c','d']
B=[1,2,3,4,5,6,7,8,9]
new_tup=zip_longest(A,B,fillvalue='BLANK')
print(list(new_tup))
组合产生器
combinations 从一个迭代器中创建一个迭代器,迭代器元素相同(按长度进行组合的新迭代对象),不会创建重复的组合
from itertools import combinations
A = 'txdT'
new_iter=combinations(A,2)
for item in new_iter:
print(''.join(item))
print(item)
结果:
tx
('t', 'x')
td
('t', 'd')
tT
('t', 'T')
xd
('x', 'd')
xT
('x', 'T')
dT
('d', 'T')
combinations_with_replacement 在combinations基础上加(tt,xx,dd,TT)
permutations 在combinations基础上加(xt,dt,Tt,dx,Tx,Td)
product 从输入中创建笛卡尔积
from itertools import product
A=[('A','B'),(1,2),("大","小")]
new_dke=product(*A)
print(list(new_dke))
结果:[('A', 1, '大'), ('A', 1, '小'), ('A', 2, '大'), ('A', 2, '小'), ('B', 1, '大'), ('B', 1, '小'), ('B', 2, '大'), ('B', 2, '小')]