ActiveState Code

Recipe 439095: Iterator to return items N-at-a-time


Creates an iterator which returns N-tuples built from the incoming items from another iterator. Useful, for example, when you need items two at a time.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
def group(iterator, count):
    itr = iter(iterator)
    while True:
        yield tuple([itr.next() for i in range(count)])


>>> group([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 2)
<generator object at 0xb7debcac>
>>> list(_)
[(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)]

>>> list(group([0, 1, 2, 3, 4, 5, 6], 2))
[(0, 1), (2, 3), (4, 5)]

>>> dataset = ['Nausori', 5, True, 'Namadi', 10, True, 'Lautoka', 8, False, 'Suva', 3, True]
>>> for place, value, truth in group(dataset, 3):
...   if truth:
...     print '%s: %s' % (place, value)
... 
Nausori: 5
Namadi: 10
Suva: 3

Discussion

I have often needed to extract items from a sequence or iterator two or three at a time. This short function makes that simple.

In the event the incoming iterator runs out of items before there are enough to fill up an N-tuple, the partial tuple is discarded. (The StopIteration exception raised by itr.next() propogates through group() and shows up to the caller as if group() raised it, thereby causing iteration through group() to end.)

Comments

  1. 1. At 12:40 p.m. on 29 jan 2006, Dug Song said:

    using itertools.imap().

    import itertools
    
    def group2(iterator, count):
        return itertools.imap(None, *([ iter(iterator) ] * count))
    

    or just map(), if you want a partial last tuple to be filled out with None...

Sign in to comment