首页 > 代码库 > python itertools模块练习

python itertools模块练习

参考 《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

 

python itertools模块练习