参考 《python标准库》
也可以参考Vamei博客
列表用着很舒服,但迭代器不需要将所有数据同时存储在内存中。
本章练习一下python 标准库中itertools模块
合并 和 分解 迭代器
-
1.chain()
处理多个序列,而不比构造一个大的,两个合在一起,遍历就好了
>>> for i in chain(range(3),range(5,9)): ... print i ... 0 1 2 5 6 7 8 >>>
-
2.izip()
类似zip,可以看出,izip 是生成迭代器了,而zip是列表
>>> for i in izip(range(5),range(11,15)): ... print i ... (0, 11) (1, 12) (2, 13) (3, 14) >>> zip(range(5),range(11,15)) [(0, 11), (1, 12), (2, 13), (3, 14)] >>> izip(range(5),range(11,15)) <itertools.izip object at 0x7fcef2848560>
-
3.islice() 按索引返回由输入迭代器所选的元素
可以看到和slice的用法差不多,就正常切片
>>> for i in islice(count(),5): ... print i ... 0 1 2 3 4 >>> for i in islice(count(),15,20): ... print i ... 15 16 17 18 19 >>> for i in islice(count(),0,100,20): ... print i ... 0 20 40 60 80 >>>
-
4.tee()
正常的迭代器搞完了就GG了,这个就类似于复制迭代器,生成两个子的并列使用父迭代器,用了子的,父的就不能用了,尽量使用并列的迭代器,看例子。
#!/usr/bin/python #coding=utf-8 #__author__='dahu' # from itertools import * r=islice(count(),5) i1,i2=tee(r,2) i3,i4=tee(i1,2) for ss in i3: #ok print ss, print '-'*5 for ss1 in i4: #ok print ss1, print '-'*5 for ss1 in i2: #ok print ss1, print '-'*5 for ss1 in i1: #NG print ss1, print '-'*5 for ss1 in r: #NG print ss1, print '-'*5 /usr/bin/python2.7 /home/dahu/nltk_data/my_itertools.py 0 1 2 3 4 ----- 0 1 2 3 4 ----- 0 1 2 3 4 ----- ----- ----- Process finished with exit code 0
转换输入
-
5.imap()
这特么也能跟map一样?毙了狗了,试一试,效果果然一样,imap,前面一个函数,后面一个迭代器,返回一个迭代器,还记得map的用法吗?看python函数式编程吧。
#!/usr/bin/python #coding=utf-8 #__author__='dahu' # from itertools import * for i in imap(lambda x:2*x,range(5)): print i print imap(lambda x:2*x,range(5)) for i in imap(lambda x,y:x+y,range(11,15),islice(count(),4)): print i /usr/bin/python2.7 /home/dahu/nltk_data/my_itertools.py 0 2 4 6 8 <itertools.imap object at 0x7f6e14f85710> 11 13 15 17 Process finished with exit code 0
-
6.starmap()
两个问题,1、imap和starmap的区别?2、starmap对应在列表上是哪个函数的?注意他们返回的都是迭代器
想了想,1、imap类似于map,只是返回迭代器而已,而starmap,第二个参数是元祖构成的列表,用*来分解(还记得**吗?就是分解字典的),当然这个例子的解决方案不是只有一个,我用列表解析和生成器解析又做了一遍,现在理解起来更透彻了,反正想节省内存,就往迭代器靠一靠。2、好像没有,函数式编程的内置函数就4个,感觉不一样。
这里,map()有两个参数,一个是lambda所定义的函数对象,一个是包含有多个元素的表。
re = map((lambda x: x+3),[1,3,5,6])
#!/usr/bin/python #coding=utf-8 #__author__='dahu' # from itertools import * a=zip(range(1,5),range(11,15)) print a for i in starmap(lambda x,y:x+y,a): print i print starmap(lambda x,y:x+y,a) t=(i[0]+i[1] for i in a) print t for i in (i[0]+i[1] for i in a): print i /usr/bin/python2.7 /home/dahu/nltk_data/my_itertools.py [(1, 11), (2, 12), (3, 13), (4, 14)] 12 14 16 18 <itertools.starmap object at 0x7ff63d8396d0> <generator object <genexpr> at 0x7ff63d83f050> 12 14 16 18 Process finished with exit code 0
生成新值
-
7.count()
一直搞下去,搞来搞去的,不停
-
8.cycle()
这个更虎,不停的搞,搞完了,再搞一次,真特么牛逼
#!/usr/bin/python #coding=utf-8 #__author__='dahu' # from itertools import * for i,j in izip(range(7),cycle(['a','b','c'])): print i,j /usr/bin/python2.7 /home/dahu/nltk_data/my_itertools.py 0 a 1 b 2 c 3 a 4 b 5 c 6 a Process finished with exit code 0
-
9.repeat()
字面意思,随你怎么搞,老子就不变
#!/usr/bin/python #coding=utf-8 #__author__='dahu' # from itertools import * for i in repeat('wocao',5): print i /usr/bin/python2.7 /home/dahu/nltk_data/my_itertools.py wocao wocao wocao wocao wocao Process finished with exit code 0
稍微跟别的合体一下 这个可以有,我以后计数用这个,以前各种range(),烦的很
#!/usr/bin/python #coding=utf-8 #__author__='dahu' # from itertools import * for i,j in izip(count(),repeat('wocao',5)): print i,j /usr/bin/python2.7 /home/dahu/nltk_data/my_itertools.py 0 wocao 1 wocao 2 wocao 3 wocao 4 wocao Process finished with exit code 0
过滤
-
10.dropwhile() takewhile()
这两个函数刚好相反,dropwhile()返回第一次条件false后,剩余所有的元素,也包括这个false的元素
takewhile()返回没有遇到条件false前,所有正确的元素,不包括这个false的元素
我感觉这个就是类似于测试,或者qc,我检查一下,takewhile()反正返回的都是满足条件的,dropwhile()返回的,那肯定是不满足条件才返回的,第一个就是false,剩余的不知道。
#!/usr/bin/python #coding=utf-8 #__author__='dahu' # from itertools import * for i in dropwhile(lambda x:x<1,[-1,0,1,-1,3]): print i print '-'*10 for i in takewhile(lambda x:x<1,[-1,0,1,-1,3]): print i /usr/bin/python2.7 /home/dahu/nltk_data/my_itertools.py 1 -1 3 ---------- -1 0 Process finished with exit code 0
-
11.ifilter() ifilterfalse()
和filter类似,只返回true,ifilterfalse()只返回false
#!/usr/bin/python #coding=utf-8 #__author__='dahu' # from itertools import * for i in ifilter(lambda x:x<1,[-1,0,1,-1,3]): print i print ifilter(lambda x:x<1,[-1,0,1,-1,3]) /usr/bin/python2.7 /home/dahu/nltk_data/my_itertools.py -1 0 -1 <itertools.ifilter object at 0x7f660dda96d0> Process finished with exit code 0
数据分组
-
12.groupby()
排序后,按数据进行分组,参考了cookbook3的例子
扩展
书上没的,现在更新了
-
13.compress()
根据第二个参数的真假情况,输出第一个参数
#!/usr/bin/python #coding=utf-8 #__author__='dahu' # from itertools import * print compress('ABCD', [1, 1, 1, 0]) for i in compress('ABCD', [1, 1, 1, 0]): print i /usr/bin/python2.7 /home/dahu/nltk_data/my_itertools.py <itertools.compress object at 0x7f91386306d0> A B C Process finished with exit code 0
-
14product()
多个循环器集合的笛卡尔积。相当于嵌套循环
from itertools import * for m, n in product('abc', [1, 2]): print m, n /usr/bin/python2.7 /home/dahu/nltk_data/my_itertools.py a 1 a 2 b 1 b 2 c 1 c 2 Process finished with exit code 0
-
15 排列组合
permutations('abc', 2) # 从'abcd'中挑选两个元素,比如ab, bc, ... 将所有结果排序,返回为新的循环器。
注意,上面的组合分顺序,即ab, ba都返回。
combinations('abc', 2) # 从'abcd'中挑选两个元素,比如ab, bc, ... 将所有结果排序,返回为新的循环器。
注意,上面的组合不分顺序,即ab, ba的话,只返回一个ab。
combinations_with_replacement('abc', 2) # 与上面类似,但允许两次选出的元素重复。即多了aa, bb, cc
#!/usr/bin/python #coding=utf-8 #__author__='dahu' # from itertools import * for m in permutations('abc', 2): print m print '-'*10 for i in combinations('abc', 2): print i print '-'*10 for i in combinations_with_replacement('abc', 2): print i /usr/bin/python2.7 /home/dahu/nltk_data/my_itertools.py ('a', 'b') ('a', 'c') ('b', 'a') ('b', 'c') ('c', 'a') ('c', 'b') ---------- ('a', 'b') ('a', 'c') ('b', 'c') ---------- ('a', 'a') ('a', 'b') ('a', 'c') ('b', 'b') ('b', 'c') ('c', 'c') Process finished with exit code 0