介绍Python中内置的itertools模块


Posted in Python onApril 29, 2015

Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数。

首先,我们看看itertools提供的几个“无限”迭代器:

>>> import itertools
>>> natuals = itertools.count(1)
>>> for n in natuals:
...   print n
...
1
2
3
...

因为count()会创建一个无限的迭代器,所以上述代码会打印出自然数序列,根本停不下来,只能按Ctrl+C退出。

cycle()会把传入的一个序列无限重复下去:

>>> import itertools
>>> cs = itertools.cycle('ABC') # 注意字符串也是序列的一种
>>> for c in cs:
...   print c
...
'A'
'B'
'C'
'A'
'B'
'C'
...

同样停不下来。

repeat()负责把一个元素无限重复下去,不过如果提供第二个参数就可以限定重复次数:

>>> ns = itertools.repeat('A', 10)
>>> for n in ns:
...   print n
...

打印10次'A'

无限序列只有在for迭代时才会无限地迭代下去,如果只是创建了一个迭代对象,它不会事先把无限个元素生成出来,事实上也不可能在内存中创建无限多个元素。

无限序列虽然可以无限迭代下去,但是通常我们会通过takewhile()等函数根据条件判断来截取出一个有限的序列:

>>> natuals = itertools.count(1)
>>> ns = itertools.takewhile(lambda x: x <= 10, natuals)
>>> for n in ns:
...   print n
...

打印出1到10

itertools提供的几个迭代器操作函数更加有用:
chain()

chain()可以把一组迭代对象串联起来,形成一个更大的迭代器:

for c in chain('ABC', 'XYZ'):
  print c
# 迭代效果:'A' 'B' 'C' 'X' 'Y' 'Z'

groupby()

groupby()把迭代器中相邻的重复元素挑出来放在一起:

>>> 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:

>>> 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']

imap()

imap()和map()的区别在于,imap()可以作用于无穷序列,并且,如果两个序列的长度不一致,以短的那个为准。

>>> for x in itertools.imap(lambda x, y: x * y, [10, 20, 30], itertools.count(1)):
...   print x
...
10
40
90

注意imap()返回一个迭代对象,而map()返回list。当你调用map()时,已经计算完毕:

>>> r = map(lambda x: x*x, [1, 2, 3])
>>> r # r已经计算出来了
[1, 4, 9]

当你调用imap()时,并没有进行任何计算:

>>> r = itertools.imap(lambda x: x*x, [1, 2, 3])
>>> r
<itertools.imap object at 0x103d3ff90>
# r只是一个迭代对象

必须用for循环对r进行迭代,才会在每次循环过程中计算出下一个元素:

>>> for x in r:
...   print x
...
1
4
9

这说明imap()实现了“惰性计算”,也就是在需要获得结果的时候才计算。类似imap()这样能够实现惰性计算的函数就可以处理无限序列:

>>> r = itertools.imap(lambda x: x*x, itertools.count(1))
>>> for n in itertools.takewhile(lambda x: x<100, r):
...   print n
...

结果是什么?

如果把imap()换成map()去处理无限序列会有什么结果?

>>> r = map(lambda x: x*x, itertools.count(1))

结果是什么?

ifilter()

不用多说了,ifilter()就是filter()的惰性实现。
小结

itertools模块提供的全部是处理迭代功能的函数,它们的返回值不是list,而是迭代对象,只有用for循环迭代的时候才真正计算。

Python 相关文章推荐
python实现合并两个数组的方法
May 16 Python
python获取当前运行函数名称的方法实例代码
Apr 06 Python
Python xlwt设置excel单元格字体及格式
Apr 18 Python
Python实现绘制双柱状图并显示数值功能示例
Jun 23 Python
Random 在 Python 中的使用方法
Aug 09 Python
Python文件操作中进行字符串替换的方法(保存到新文件/当前文件)
Jun 28 Python
Python pandas实现excel工作表合并功能详解
Aug 29 Python
查看端口并杀进程python脚本代码
Dec 17 Python
解决Tensorflow sess.run导致的内存溢出问题
Feb 05 Python
python json load json 数据后出现乱序的解决方案
Feb 27 Python
python 实现非极大值抑制算法(Non-maximum suppression, NMS)
Oct 15 Python
Pandas实现批量拆分与合并Excel的示例代码
May 30 Python
python使用fileinput模块实现逐行读取文件的方法
Apr 29 #Python
python将字符串转换成数组的方法
Apr 29 #Python
Python中使用hashlib模块处理算法的教程
Apr 28 #Python
简单介绍Python中的struct模块
Apr 28 #Python
在Python中使用base64模块处理字符编码的教程
Apr 28 #Python
使用Python的内建模块collections的教程
Apr 28 #Python
进一步探究Python中的正则表达式
Apr 28 #Python
You might like
两种php调用Java对象的方法
2006/10/09 PHP
php把数据表导出为Excel表的最简单、最快的方法(不用插件)
2014/05/10 PHP
php实现在服务器上创建目录的方法
2015/03/16 PHP
PHP让网站移动访问更加友好方法
2019/02/14 PHP
js 禁用浏览器的后退功能的简单方法
2008/12/10 Javascript
分享一个我自己写的ToolTip提示插件(附源码)
2013/01/20 Javascript
JQuery给元素绑定click事件多次执行的解决方法
2014/05/29 Javascript
JSP中使用JavaScript动态插入删除输入框实现代码
2014/06/13 Javascript
jQuery不兼容input的change事件问题解决过程
2014/12/05 Javascript
javascript强制点击广告的方法
2015/02/06 Javascript
jquery实现浮动的侧栏实例
2015/06/25 Javascript
基于jQuery日历插件制作日历
2016/03/11 Javascript
jQuery在ie6下无法设置select选中的解决方法详解
2016/09/20 Javascript
使用DeviceOne实现微信小程序功能
2016/12/29 Javascript
JavaScript中String对象的方法介绍
2017/01/04 Javascript
Node.js v8.0.0正式发布!看看带来了哪些主要新特性
2017/06/02 Javascript
js实现动态添加上传文件页面
2018/10/22 Javascript
NodeJS模块Buffer原理及使用方法解析
2020/11/11 NodeJs
[02:59]2014DOTA2西雅图国际邀请赛 圆满落幕中国夺冠
2014/07/23 DOTA
python django事务transaction源码分析详解
2017/03/17 Python
200 行python 代码实现 2048 游戏
2018/01/12 Python
python3 http提交json参数并获取返回值的方法
2018/12/19 Python
对Django中static(静态)文件详解以及{% static %}标签的使用方法
2019/07/28 Python
pandas DataFrame的修改方法(值、列、索引)
2019/08/02 Python
python根据时间获取周数代码实例
2019/09/30 Python
浅谈tensorflow中张量的提取值和赋值
2020/01/19 Python
python requests.get带header
2020/05/05 Python
利用HTML5中Geolocation获取地理位置调用Google Map API在Google Map上定位
2013/01/23 HTML / CSS
TUMI澳大利亚网站:美国旅行箱包品牌
2017/03/27 全球购物
微软台湾官方网站:Microsoft台湾
2018/08/15 全球购物
客运企业隐患排查工作方案
2014/06/06 职场文书
2014年秋季开学典礼致辞
2014/08/02 职场文书
不服从公司安排检讨书
2014/09/24 职场文书
民事答辩状格式范文
2015/05/21 职场文书
就业指导讲座心得体会
2016/01/15 职场文书
MySQL慢查询优化解决问题
2022/03/17 MySQL