当前位置: 首页 > 后端技术 > Python

itertools--高效迭代器│Python标准库

时间:2023-03-26 12:15:55 Python

初步提示:测试代码中,右尖括号(>)表示命令行输入的命令;输出内容是以哈希字符(#)开头的单行;库的导入仅在本文第一个测试代码中展示,其他代码块中省略了库的导入代码。系统类型:Windows10python版本:Python3.9.0itertools模块标准化了一个快速、内存高效的核心工具集,主要用于实现一系列迭代器。这些效用函数可以单独使用,也可以相互组合使用。它们一起构成了迭代器代数。itertools模块中的所有函数都创建并返回一个迭代器。它们的区别在于迭代器生成的内容和使用场景。无限迭代器无限迭代器最大的特点就是可以无限迭代元素,所以在使用的时候一定要注意限制,控制迭代器的停止,否则会造成死循环。itertools.count(start=0,step=1)开始:int|浮点数,起始值步长:int|float,step创建一个迭代器,第一个元素的值为参数start的值,后面元素的值按照参数step的值依次累加。importitertools'''打印迭代器本身'''print(itertools.count(7,1))#count(7)'''迭代器类型'''print(type(itertools.count(7,1)))#'''一个简单的小应用程序'''foriinitertools.count(7,1):print(i)ifi>10:break#7#8#9#10#11itertools模块中使用的函数返回的迭代器类型与函数同名,在使用迭代器的场景下可以直接使用。itertools.cycle(iterable)iterable:一个可迭代对象创建一个迭代器,根据传入的迭代器中的元素,返回这些元素,当这些元素被取到时,会从第一个元素重新获取,无限重复。'''小型应用程序,当获取第三个A时停止'''test_str=''foriinitertools.cycle('ABC'):test_str+=iiftest_str.count('A')>=3:breakprint(test_str)#ABCABCAitertools.repeat(object[,times])object:python对象,可以是任意数据times:int,迭代次数,可选参数,默认无限创建迭代器并重复对象。如果设置了次数,则最多重复多次,否则重复无限次。通常用作map()函数中的参数之一。'''有限迭代器'''print(list(itertools.repeat(10,3)))#[10,10,10]'''使用map()函数在两个迭代器元素之间pow()结果为collected'''print(list(map(pow,range(10),itertools.repeat(2))))#[0,1,4,9,16,25,36,49,64,81]以上无限迭代器使用自身条件或外部限制进行测试,使其迭代有限次数。这些函数生成的迭代器通常用于迭代次数不确定的场景。迭代器操作及处理itertools.accumulate(iterable[,func,*,initial=None])iterable:可迭代对象func:函数,有两个参数,可选参数initial:关键字参数,默认为None,如果将此参数作为参数传递,此参数将用作iterable的第一个元素来创建迭代器。默认情况下,将返回累积的汇总值。如果传入func,则按照func中的方法执行。例如:如果iterable是[1,2,3],返回的迭代器是[1,1+2,1+2+3]。'''默认返回累计汇总值'''print(list(itertools.accumulate([1,2,3,4,5])))#[1,3,6,10,15]'''修改方法计算累加积'''print(list(itertools.accumulate([1,2,3,4,5],lambdax,y:x*y)))#[1,2,6,24,120]'''在迭代器起始位置添加一个元素,方法不变,返回累计汇总值'''print(list(itertools.accumulate([1,2,3,4,5],initial=100)))#[100,101,103,106,110,115]'''在迭代器起始位置添加一个元素,方法修改为计算累加积'''print(list(itertools.accumulate([1,2,3,4,5],lambdax,y:x*y,initial=10)))#[10,10,20,60,240,1200]itertools.chain(*iterables)*iterables:很多个Iterable对象,用逗号隔开创建一个迭代器,将多个可迭代对象的元素添加到迭代器中。'''将多个可迭代对象集成到一个迭代器'''temp=itertools.chain([1,2,3],('A','B','C'),{'one','two','三'})print(list(temp))#[1,2,3,'A','B','C','一','三','二']itertools。chain.from_iterable(iterable)iterable:可迭代对象类似于itertools.chain()函数,但是参数是一个可迭代对象,将可迭代对象中的元素一个一个添加到新的迭代器中,如果元素是一个可迭代对象,那么这个元素内的元素将被一个一个地添加到新的迭代器中。小编自己的理解就是迭代器降维。'''二维迭代器的降维'''temp=itertools.chain.from_iterable(['1',['2','3'],('4','5')])print(list(temp))#['1','2','3','4','5']'''只能降一级维度,三维会降为二维'''temp=itertools.链。from_iterable(['1',['2','3'],('4',['5','6'])])print(list(temp))#['1','2','3','4',['5','6']]PS:迭代器维度的概念可以理解为整个迭代器中的元素要么是迭代器类型,要么是一维的,而迭代器中的元素如果有迭代器就是二维的,如果迭代器中的元素是迭代器,那么如果这个迭代器中有元素是迭代器就是三维的,以此类推。itertools.compress(data,selectors)data:iterableobject,containingtherequireddataselectors:iterableobject,truthtestdata创建迭代器,保留data中被selectors真值测试为True的元素。当两个可迭代对象之一到达末尾时,执行停止,返回最终结果。'''只判断前三个元素,索引值为0和2的元素将保留在新的迭代器中并返回'''temp=itertools.compress(['A','B','C','D'],[1,0,1])print(list(temp))#['A','C']itertools.dropwhile(predicate,iterable)predicate:一个只需要一个参数可迭代的函数:iterable对象创建一个迭代器,并根据perdicate函数依次计算iterable中的元素。当第一次计算结果为假时,丢弃该元素之前的所有元素,其余(包括计算结果为负的元素)保留给新的迭代器使用。这个函数的实际运行过程是:计算第一个元素,如果为True,则不返回,然后计算下一个元素,如果为True,则不返回,直到第N个元素的计算结果为False,则返回该元素,后面的所有元素都不计算,直接返回。'''真值测试'''temp=itertools.dropwhile(bool,[1,2,0,3])print(list(temp))#[0,3]'''元素的值减去2小于或等于0为真'''temp=itertools.dropwhile(lambdax:x-2<=0,[1,2,0,3,1])print(list(temp))#[3,1]itertools。takewhile(predicate,iterable)predicate:一个只需要一个参数的函数功能。当结果布尔值为True时,其元素被添加到新的迭代器中,直到一个元素的计算结果为False,该元素和所有后续元素都被丢弃。temp=itertools.takewhile(bool,[1,3,None,0,1])print(list(temp))#[1,3]itertools.filterfalse(predicate,iterable)predicate:一个只需要一个的可迭代函数parameter:IterableObject创建一个迭代器,该迭代器仅保留在谓词评估中为False的iterable中的元素。如果predicate传入None,相当于传入bool,意思是做真值检验。'''元素的值减去2小于等于0为True'''temp=itertools.filterfalse(lambdax:x-2<=0,[1,2,0,3,1])print(list(temp))#[3]'''真实性测试'''temp=itertools.filterfalse(None,[1,2,0,3,1])print(list(temp))#[0]itertools.groupby(iterable,key=None)iterable:iterableobjectkey:执行创建迭代器的函数,通过key依次通过iterable的元素计算结果,为每个结果创建一个列表,并使用结果作为列表的第一个元素,所有results以这个值作为列表的第二个元素的元素组成一个迭代器,最后将这些列表保存到新的迭代器中并返回。在返回的迭代器中,列表中的第二个元素也是一个迭代器,类型与返回的迭代器一致,是共享底层的可迭代对象。因为源是共享的,所以在对返回的迭代器进行操作时,总是会得到一个空值,所以如果后面的程序中需要用到这些数据,就必须手动保存到列表或者其他位置。'''真实性测试'''groups=[]fork,ginitertools.groupby([0,3,2,1,4],bool):groups.append((k,list(g)))打印(groups)#[(False,[0]),(True,[3,2,1,4])]itertools.islice(iterable,start,stop[,step])iterable:可迭代对象start:start起始位置stop:endpositionstep:step创建一个从iterable返回被选元素的迭代器,被选元素从startindex位置开始,以step为step,结束于stopindex位置。列表、字符串等切片操作。使用itertools.islice()函数时,也可以只传入iterable和stop参数。如果只有这两个参数,start默认为0,step默认为1。如果stop参数传None,则默认直到迭代器结束。start、stop、step这三个参数不支持负数。iterable=[0,1,2,3,4,5,6,7,8,9]'''结束位置7'''print(list(itertools.islice(iterable,7)))#[0,1,2,3,4,5,6]'''开始位置1,结束位置7'''print(list(itertools.islice(iterable,1,7)))#[1,2,3,4,5,6]'''开始位置1,结束位置到结束'''print(list(itertools.islice(iterable,1,None)))#[1,2,3,4,5,6,7,8,9]'''开始位置1,结束位置7,步长2'''print(list(itertools.islice(iterable,1,7,2)))#[1,3,5]itertools.starmap(function,iterable)function:functioniterable:iterableobject创建一个迭代器,计算iterable中的元素作为函数的参数,并将结果保存在新的迭代器中。iterable中的每个元素都是一个元组,其中包含函数所需的参数。'''使用starmap()和map()得到相同的结果'''temp=itertools.starmap(pow,[(1,2),(3,4),(5,6)])print(list(temp))#[1,81,15625]print(list(map(pow,(1,3,5),(2,4,6))))#[1,81,15625]itertools.tee(iterable,n=2)iterable:可迭代对象n:默认值为2,splititerators的个数从一个可迭代对象中拆分出n个独立的可迭代对象并返回。因为我在itertools中。tee([1,2,3,4,5,6],2):print(list(i))#[1,2,3,4,5,6]#[1,2,3,4,5,6]itertools.zip_longest(*iterables,fillvalue=None)*iterables:一个或多个可迭代对象fillvalue:关键字参数,填充值,默认为None从所有传入的iterable中创建一个迭代器从传入的iterable中提取一个元素,组合它们组成一个元组,并将其添加到迭代器中。当传入的可迭代对象中的元素已经被读取,并且还有其他可迭代对象的元素还没有被读取时,缺失的部分会根据参数fillvalue的值进行填充。读取所有传递的迭代器后,返回一个新的迭代器。temp=itertools.zip_longest('xyz','123456','Darkness',fillvalue='*')print(list(temp))#[('x','1','dark'),('y','2','语言'),('z','3','冷'),('*','4','飞'),('*','5','*'),('*','6','*')]排列组合乘积(*iterables,repeat=1)*iterables:一个或多个可迭代对象repeat:关键字参数,重复次数,defaultComputestheCartesian1与一个或多个可迭代对象的乘积。也就是说,对于前一个可迭代对象的元素和下一个可迭代对象的元素的所有组合,为每个组合生成一个元组并添加到新的迭代器中。参数repeat是传入的可迭代对象的重复次数,例如:product('AB',repeat=2)等价于product('AB','AB')。temp=itertools.product('ABC','XY')print(list(temp))#[('A','X'),('A','Y'),('B','X''),('B','Y'),('C','X'),('C','Y')]temp=itertools.product('AB','XY',repeat=2)print(list(temp))#[('A','X','A','X'),('A','X','A','Y'),('A','X','B','X'),('A','X','B','Y'),#('A','Y','A','X'),('A','Y','A','Y'),('A','Y','B','X'),('A','Y','B','Y'),#('B','X','A','X'),('B','X','A','Y'),('B','X','B','X'),('B','X','B','Y'),#('B','Y','A','X'),('B','Y','A','Y'),('B','Y','B','X'),('B','Y','B','Y')]permutations(iterable,r=None)iterable:可迭代对象r:关键字参数,新元素的长度,默认为None,即新元素的长度为元素个数,将元素排列在可迭代的长度为r。每个排列产生一个元组,该元组被添加到一个新的迭代器中。排序时,排序顺序按照iterable中元素的先后顺序。因此,未排序的可迭代对象和已排序的可迭代对象的排列方式不同。如果iterable中有值相同的元素,但是它们的位置不同,在排列的时候会认为是不同的。PS:排列是一种数学排列,是n个元素中m个元素的不重复排列或直线排列。'''排列4个长度为2的元素'''temp=itertools.permutations('ABCD',2)print(list(temp))#[('A','B'),('A','C'),('A','D'),('B','A'),('B','C'),('B','D'),('C','A'),('C','B'),('C','D'),('D','A'),('D','B'),('D','C')'''排列3个长度为3的元素'''temp=itertools.permutations('ABC')print(list(temp))#[('A','B','C'),('A','C','B'),('B','A','C'),('B','C','A'),('C','A','B'),('C','B','A')]combinations(iterable,r)iterable:可迭代对象r:新元素的长度将是iterable中长度为r的元素排列。每个排列产生一个元组,该元组被添加到一个新的迭代器中。与permutations()函数基本相同,但是combinations()函数会过滤掉元素值一致的元组。'''过滤掉元素值相同的元组'''temp=itertools.combinations('ABC',2)print(list(temp))#[('A','B'),('A','C'),('B','C')]'''对照组'''temp=itertools.permutations('ABC',2)print(list(temp))#[('A','B'),('A','C'),('B','A'),('B','C'),('C','A'),('C','B')]combinations_with_replacement(iterable,r)iterable:可迭代对象r:关键字参数,新元素的长度,默认为None,即新元素的长度为元素个数。combinations()函数的一种变体,保留用于过滤基于元素值一致的元组的功能,该函数还会将元素本身与它们所在的可迭代对象进行排列。'''会和它所在的可迭代对象一起排列'''temp=itertools.combinations_with_replacement('ABC',2)print(list(temp))#[('A','A'),('A','B'),('A','C'),('B','B'),('B','C'),('C','C')]'''对比设置'''temp=itertools.permutations('ABC',2)print(list(temp))#[('A','B'),('A','C'),('B','C')]公众号:《python杂货店》,重点讲解python语言及相关知识。发现更多原创文章,期待您的关注。参考官方文档:https://docs.python.org/zh-cn...