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

  • 相关阅读:
    php RSA加密传输代码示例
    数据库执行语句时,严重注意类型转换的问题
    数据库sql的in操作,解决in的过多
    php利用自定义key,对数据加解密的方法
    修改目录下所有文件的某段内容
    ajax返回json时,js获取类型,是字符串类型
    浅析单点登录,以及不同二级域名下的SSO实现
    samba服务,连接远程开发机
    『转』统计一个日志文件里,单词出现频率的shell脚本
    python的装饰器
  • 原文地址:https://www.cnblogs.com/jaw-crusher/p/3516592.html
Copyright © 2011-2022 走看看