今天在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就对了,如果能看看文档中的等价代码,想必是理解这些函数极好的途径。