美文网首页python进阶
itertools模块详解

itertools模块详解

作者: nummycode | 来源:发表于2016-10-08 19:41 被阅读285次

    itertools模块包含一组函数用于处理序列数据集。

    合并和分解迭代器

    • chain 用于合并多个迭代器, 利用chain可以轻松处理多个序列。
    from itertools import chain
    
    for i in chain([1,2,3], ['a', 'b', 'c'])
        print i
    

    结果为:

    1
    2
    3
    a
    b
    c
    
    • izip 用于将多个迭代器中的元素组合到一个元组中
    from itertools import izip
    for i in izip([1,2,3], ['a','b', 'c']):
        print i
    

    结果为:

    (1,'a')
    (2,'b')
    (3,'c')
    
    • islice 返回一个迭代器,它按索引返回由输入迭代器所选的元素。
    from itertools import *
    
    print "Stop at 5“
    for i in islice(count(), 5):
        print i
        
    print "Start at 5, stop at 10"
    for i in islice(count(), 5,10):
        print i
        
    print "By tens to 100"
    for i in islice(count(), 0, 100, 10):
        print i
    

    count()用于生成无限连续整数,后面会讲到。

    • tee 根据一个原输入迭代器返回多个独立的迭代器, 默认为两个。
    from itertools import *
    r = islice(count(), 5)
    i1, i2 = tee(r)
    

    tee()创建的迭代器共享其输入迭代器,所以一旦创建了新迭代器,就不应该再使用远迭代器。

    如果原迭代器的值已经使用,新迭代器不会再生成这些值。

    转换输入

    • imap 返回一个迭代器,它对输入迭代器中的值调用一个函数并返回结果。imap函数的工作方式类似于内置函数map,只不过只要某个输入迭代器中的元素使用完,imap函数就会停止。
    from itertools import *
    
    print "Doubles:"
    for i in imap(lambda x:2*x, xrange(5)):
        print i
    
    print "Multiples:"
    for i in imap(lambda x, y:(x,y, x*y), xrange(5), xrange(5, 10)):
        print '%d * %d = %d' % i
    

    结果如下:

    Doubles:
    0
    2
    4
    6
    8
    Multiples:
    0 * 5 = 0
    1 * 6 = 6
    2 * 7 = 14
    3 * 8 = 24
    4 * 9 = 36
    
    • starmap starmap类似于imap函数,不过它并不是使用多个迭代器来构建一个tuple, 而是使用*语法来分解一个迭代器中的元素来作为映射函数的参数。
    from itertools import *
    
    values = [[0,5], [1,6], [2,7], [3,8]]
    
    for i in starmap(lambda x, y:(x, y, x*y), values):
        print '%d * %d = %d' % i
    

    输出结果如下:

    0 * 5 = 0
    1 * 6 = 6
    2 * 7 = 14
    3 * 8 = 24
    

    imap的函数映射名为f(i1, i2), 而传入starmap()的映射函数名为f(*i)。

    生成新值

    • count 返回一个迭代器,能够无限的生成连续整数,第一个数可以作为参数传入,默认为0,这里没有上界参数。
    from itertools import *
    
    for i in izip(count(1), ['a', 'b', 'c']):
        print i
    

    输出结果如下:

    (1, 'a')
    (2, 'b')
    (3, 'c')
    
    • cycle 返回一个迭代器,它会无限的重复给定参数的内容。由于必须记住输入迭代器的全部内容,因此如果这个迭代器比较长,可能会比较消耗内存。
    from itertools import *
    
    for i in izip(xrange(7), cycle(['a', 'b', 'c'])):
        print i
    

    输出结果如下:

    (0, 'a')
    (1, 'b')
    (2, 'c')
    (3, 'a')
    (4, 'b')
    (5, 'c')
    (6, 'a')
    
    • repeat 返回一个迭代器,每次访问都会生成相同的值。
    from itertools import *
    
    for i in repeat("over and over ", 5):
        print i
    

    输出结果如下:

    over and over 
    over and over 
    over and over 
    over and over 
    over and over 
    

    repeat返回的迭代器会一直返回数据,除非提供了可选的times参数来限制次数。

    过滤

    • dropwhile 该函数返回一个迭代器,它会生成输入迭代器中条件第一次为false之后的元素。
    from itertools import *
    
    def should_drop(x):
        print "Testing:", x
        return (x<1)
    
    for i in dropwhile(should_drop, [-1, 0, 1, 2, -2]):
        print "Yielding:", i
    

    输出结果如下:

    Testing: -1
    Testing: 0
    Testing: 1
    Yielding: 1
    Yielding: 2
    Yielding: -2
    

    dropwhile()函数并不会过滤输入的每一个元素,第一次条件为false之后,输入中所有余下的元素都会返回。

    • takewhile 该函数与dropwhile正好相反,它也返回一个迭代器,这个迭代器生成输入迭代器中条件第一次为false之前的元素。
    from itertools import *
    
    def should_take(x):
        print "Testing:", x
        return (x<2)
    
    for i in takewhile(should_take, [-1, 0, 1, 2, -2]):
        print "Yielding:", i
    

    输出结果如下:

    Testing: -1
    Yielding: -1
    Testing: 0
    Yielding: 0
    Testing: 1
    Yielding: 1
    Testing: 2
    
    • ifilter 该函数返回一个迭代器,它的工作方式与filter函数类似,只返回满足条件的元素。
    from itertools import *
    
    def check_item(x):
        print "Testing:", x
        return (x<1)
    
    for i in ifilter(check_item, [-1, 0, 1, 2, -2]):
        print "Yielding:", i
    

    输出结果如下:

    Testing: -1
    Yielding: -1
    Testing: 0
    Yielding: 0
    Testing: 1
    Testing: 2
    Testing: -2
    Yielding: -2
    
    • ifilterfalse 该函数与ifilter正好相反,只返回不满足条件的元素。
    from itertools import *
    
    def check_item(x):
        print "Testing:", x
        return (x<1)
    
    for i in ifilterfalse(check_item, [-1, 0, 1, 2, -2]):
        print "Yielding:", i
    

    输出结果如下:

    Testing: -1
    Testing: 0
    Testing: 1
    Yielding: 1
    Testing: 2
    Yielding: 2
    Testing: -2
    

    数据分组

    • groupby 该函数返回一个迭代器,它会生成一个公共键组织的值集。
    from itertools import *
    import operator
    import pprint
    
    class Point:
        def __init__(self, x, y):
            self.x = x
            self.y = y
    
        def __repr__(self):
            return "(%s, %s)" % (self.x, self.y)
    
        def __cmp__(self, other):
            return cmp((self.x, self.y), (other.x, other.y))
    
    data = list(imap(Point, cycle(islice(count(), 3)), islice(count(), 7)))
    print "Data:"
    pprint.pprint(data, width =69)
    print 
    
    print "Grouped, unsorted"
    for k, g in groupby(data, operator.attrgetter('x')):
        print k, list(g)
    print 
    
    data.sort()
    print "Sorted:"
    pprint.pprint(data, width=69)
    print
    
    print "Grouped, sorted"
    for k, g in groupby(data, operator.attrgetter('x')):
        print k, list(g)
    print 
    

    输出结果如下:

    Data:
    [(0, 0), (1, 1), (2, 2), (0, 3), (1, 4), (2, 5), (0, 6)]
    
    Grouped, unsorted
    0 [(0, 0)]
    1 [(1, 1)]
    2 [(2, 2)]
    0 [(0, 3)]
    1 [(1, 4)]
    2 [(2, 5)]
    0 [(0, 6)]
    
    Sorted:
    [(0, 0), (0, 3), (0, 6), (1, 1), (1, 4), (2, 2), (2, 5)]
    
    Grouped, sorted
    0 [(0, 0), (0, 3), (0, 6)]
    1 [(1, 1), (1, 4)]
    2 [(2, 2), (2, 5)]
    

    注意输入序列需要根据键值排序,以保证得到预期的分组。

    相关文章

      网友评论

        本文标题:itertools模块详解

        本文链接:https://www.haomeiwen.com/subject/cyzuyttx.html