您的位置:首页 > 编程语言 > Python开发

python itertools模块学习

2014-01-12 21:46 351 查看
今天在G+发现一个帖子(https://plus.google.com/u/0/114741495643730382543/posts/HWDJ5jrwuXW),

很有意思,只有一行,但是实现了一个一般要循环3次的功能,这一行神奇的代码如下:

>>> [''.join(l) for l in [list(t) for t in list(itertools.product(*[['m','p'], ['a','e'], ['n','t','w']]))]]


把它写入到一个文件里是这样的:

from itertools import product
print [''.join(l) for l in [list(t) for t in list(product(*[['m','p'], ['a', 'e'], ['n', 't', 'w']]))]]


运行结果如下:

['man', 'mat', 'maw', 'men', 'met', 'mew', 'pan', 'pat', 'paw', 'pen', 'pet', 'pew']


这让我忍不住看看itertools模块,先看看product()函数:

有点晕,只是明白这个函数会返回一个iter对象,先做个简单的代码行:

print [i for i in product('ABC', repeat=2)]


是这么个结果:

[('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'B'), ('B', 'C'), ('C', 'A'), ('C', 'B'), ('C', 'C')]


看别人的介绍,就是一个元组组成的笛卡尔积。

repeat表示乘积的次数,那么我们就不难理解那一行神奇的代码了,

先去掉一行循环:

print [list(t) for t in list(product(*[['m','p'], ['a','e'], ['n','t','w']]))]


是一个list组成的list。什么*表示什么,*表示参数可以是不定数目的意思,比如一个求和函数,不知道几个参数,可以这么写:

def sumit(*argc):
return sum(argc)

print sumit(1,2,3)
print sumit(1,2,3,4,5)


最后再加入一次list comprehension就行了。还有很多函数,选一些自己感觉比较有用的介绍一下:

1.counter(), 可以用来生成一系列数字,如生成以3为首项,4为公差的等差数列前10项:

from itertools import *

c = count(3, 4)
for i in xrange(10):
print c.next()


这里的c是一个iter对象,可以用于迭代。

和以下代码等价:

def count(start=0, step=1):
# count(10) --> 10 11 12 13 14 ...
# count(2.5, 0.5) -> 2.5 3.0 3.5 ...
n = start
while True:
yield n
n += step


2.cycle()用于生成一个循环链,如不断重复ABC ABC ABC,如果我想要知道第1001个是什么,可以这么做:

from itertools import *

c = cycle('ABC')
index = 0
while True:
res = c.next()
if index == 1000:
print res
break
index += 1


cycle()等价于以下的代码:

def cycle(iterable):
# cycle('ABCD') --> A B C D A B C D A B C D ...
saved = []
for element in iterable:
yield element
saved.append(element)
while saved:
for element in saved:
yield element


3. imap()类似于map(),不过返回的还是iter对象,而不是具体的数值。

如果求 2的5次方+3的6次方+10的3次方 可以这么做:

print sum(imap(pow, (2,3,10),(5,6,3)))


但是需要知道 imap(pow, (2,3,10),(5,6,3)) 依旧是一个对象,不是一个list。

4. tee() 用于构建一系列的iter对象,返回一个元组,如果需要两个从1-10的iter对象,可以这样做:

t = tee([i for i in range(10)], 2)
for i in range(10):
print t[0].next()


更多的函数可以自己阅读官方文档,http://docs.python.org/2/library/itertools.html

总之,这个要记住这个模块是对很多函数式关键字再次封装,返回的都是iter对象,类似大量使用yield就对了,如果能看看文档中的等价代码,想必是理解这些函数极好的途径。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: