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

和以下代码等价:

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

原文地址:https://www.cnblogs.com/jaw-crusher/p/3516592.html