python itertools模块学习

      今天在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对象,可以用于迭代。

和以下代码等价:

python itertools模块学习
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
python itertools模块学习

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

 

python itertools模块学习
from itertools import *

c = cycle(ABC)
index = 0
while True:
    res = c.next()
    if index == 1000:
        print res
        break
    index += 1
python itertools模块学习

 

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

python itertools模块学习
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
python itertools模块学习

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

python itertools模块学习

上一篇:MySQL sql万花油优化


下一篇:[android]fmodex在某些android设备上声音延迟Latency