itertools库
迭代器(生成器)在Python中是一种很常用也很好用的数据结构,比起列表(list)来说,迭代器最大的优势就是延迟计算,按需使用,从而提高开发体验和运行效率,以至于在Python 3中map,filter等操作返回的不再是列表而是迭代器。
话虽这么说但大家平时用到的迭代器大概只有range了,而通过iter函数把列表对象转化为迭代器对象又有点多此一举,这时候我们今天的主角itertools就该上场了。
使用itertools
itertools中的函数大多是返回各种迭代器对象,其中很多函数的作用我们平时要写很多代码才能达到,而在运行效率上反而更低,毕竟人家是系统库。
itertools.accumulate
简单来说就是累加。
1 2 3 4 | >>> import itertools >>> x = itertools.accumulate(range(10)) >>> print(list(x)) [0, 1, 3, 6, 10, 15, 21, 28, 36, 45] |
itertools.chain
连接多个列表或者迭代器。
1 2 3 | >>> x = itertools.chain(range(3), range(4), [3,2,1]) >>> print(list(x)) [0, 1, 2, 0, 1, 2, 3, 3, 2, 1] |
itertools.combinations
求列表或生成器中指定数目的元素不重复的所有组合
1 2 3 | >>> x = itertools.combinations(range(4), 3) >>> print(list(x)) [(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)] |
itertools.combinations_with_replacement
允许重复元素的组合
1 2 3 | >>> x = itertools.combinations_with_replacement( 'ABC' , 2) >>> print(list(x)) [( 'A' , 'A' ), ( 'A' , 'B' ), ( 'A' , 'C' ), ( 'B' , 'B' ), ( 'B' , 'C' ), ( 'C' , 'C' )] |
itertools.compress
按照真值表筛选元素
1 2 3 | >>> x = itertools.compress(range(5), (True, False, True, True, False)) >>> print(list(x)) [0, 2, 3] |
itertools.count
就是一个计数器,可以指定起始位置和步长
1 2 3 | >>> x = itertools.count(start=20, step=-1) >>> print(list(itertools.islice(x, 0, 10, 1))) [20, 19, 18, 17, 16, 15, 14, 13, 12, 11] |
itertools.cycle
循环指定的列表和迭代器
1 2 3 | >>> x = itertools.cycle( 'ABC' ) >>> print(list(itertools.islice(x, 0, 10, 1))) [ 'A' , 'B' , 'C' , 'A' , 'B' , 'C' , 'A' , 'B' , 'C' , 'A' ] |
itertools.dropwhile
按照真值函数丢弃掉列表和迭代器前面的元素
1 2 3 | >>> x = itertools.dropwhile(lambda e: e < 5, range(10)) >>> print(list(x)) [5, 6, 7, 8, 9] |
itertools.filterfalse
保留对应真值为False的元素
1 2 3 | >>> x = itertools.filterfalse(lambda e: e < 5, (1, 5, 3, 6, 9, 4)) >>> print(list(x)) [5, 6, 9] |
itertools.groupby
按照分组函数的值对元素进行分组
1 2 3 4 5 6 | >>> x = itertools.groupby(range(10), lambda x: x < 5 or x > 8) <br> >>> for condition, numbers in x: ... print(condition, list(numbers)) True [0, 1, 2, 3, 4] False [5, 6, 7, 8] True [9] |
groupby()
把迭代器中相邻的重复元素挑出来放在一起:
1 2 3 4 5 6 7 | >>> for key, group in itertools.groupby( 'AAABBBCCAAA' ): ... print key, list( group ) # 为什么这里要用list()函数呢? ... A [ 'A' , 'A' , 'A' ] B [ 'B' , 'B' , 'B' ] C [ 'C' , 'C' ] A [ 'A' , 'A' , 'A' ] |
实际上挑选规则是通过函数完成的,只要作用于函数的两个元素返回的值相等,这两个元素就被认为是在一组的,而函数返回值作为组的key。如果我们要忽略大小写分组,就可以让元素'A'
和'a'
都返回相同的key:
1 2 3 4 5 6 7 | >>> for key, group in itertools.groupby( 'AaaBBbcCAAa' , lambda c: c.upper()): ... print key, list( group ) ... A [ 'A' , 'a' , 'a' ] B [ 'B' , 'B' , 'b' ] C [ 'c' , 'C' ] A [ 'A' , 'A' , 'a' ] |
itertools.islice
上文使用过的函数,对迭代器进行切片
1 2 3 | >>> x = itertools.islice(range(10), 0, 9, 2) >>> print(list(x)) [0, 2, 4, 6, 8] |
itertools.permutations
产生指定数目的元素的所有排列(顺序有关)
1 2 3 | >>> x = itertools.permutations(range(4), 3) >>> print(list(x)) [(0, 1, 2), (0, 1, 3), (0, 2, 1), (0, 2, 3), (0, 3, 1),<br> (0, 3, 2), (1, 0, 2), (1, 0, 3), (1, 2, 0), (1, 2, 3), (1, 3, 0), (1, 3, 2),<br> (2, 0, 1), (2, 0, 3), (2, 1, 0), (2, 1, 3), (2, 3, 0), (2, 3, 1), (3, 0, 1),<br> (3, 0, 2), (3, 1, 0), (3, 1, 2), (3, 2, 0), (3, 2, 1)] |
itertools.product
产生多个列表和迭代器的(积)
1 2 3 4 5 | >>> x = itertools.product( 'ABC' , range(3)) >>> >>> print(list(x)) [( 'A' , 0), ( 'A' , 1), ( 'A' , 2), ( 'B' , 0), ( 'B' , 1), ( 'B' , 2), ( 'C' , 0), ( 'C' , 1), ( 'C' , 2)] |
itertools.repeat
简单的生成一个拥有指定数目元素的迭代器
1 2 3 | >>> x = itertools.repeat(0, 5) >>> print(list(x)) [0, 0, 0, 0, 0] |
itertools.starmap
类似map
1 2 3 | >>> x = itertools.starmap(str.islower, 'aBCDefGhI' ) >>> print(list(x)) [True, False, False, False, True, True, False, True, False] |
itertools.takewhile
与dropwhile相反,保留元素直至真值函数值为假。
1 2 3 | >>> x = itertools.takewhile(lambda e: e < 5, range(10)) >>> print(list(x)) [0, 1, 2, 3, 4] |
itertools.tee
这个函数我也不是很懂,似乎是生成指定数目的迭代器
1 2 3 4 5 6 | >>> x = itertools.tee(range(10), 2) >>> for letters in x: ... print(list(letters)) ... [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
itertools.zip_longest
类似于zip,不过已较长的列表和迭代器的长度为准
1 2 3 4 5 6 | >>> x = itertools.zip_longest(range(3), range(5)) >>> y = zip(range(3), range(5)) >>> print(list(x)) [(0, 0), (1, 1), (2, 2), (None, 3), (None, 4)] >>> print(list(y)) [(0, 0), (1, 1), (2, 2)] |
小结
itertools
模块提供的全部是处理迭代功能的函数,它们的返回值不是list,而是迭代对象,只有用for
循环迭代的时候才真正计算
本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/articles/10269329.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能