Iterate through list two items at a time

Wade Leftwich wleftwich at gmail.com
Wed Jan 3 22:43:32 EST 2007


Jeffrey Froman wrote:
> Dave Dean wrote:
>
> >  I'm looking for a way to iterate through a list, two (or more) items at a
> > time.
>
> Here's a solution, from the iterools documentation. It may not be the /most/
> beautiful, but it is short, and scales well for larger groupings:
>
> >>> from itertools import izip
> >>> def groupn(iterable, n):
> ...     return izip(* [iter(iterable)] * n)
> ...
> >>> list(groupn(myList, 2))
> [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9), (10, 11)]
> >>> list(groupn(myList, 3))
> [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]
> >>> list(groupn(myList, 4))
> [(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11)]
> >>> for a,b in groupn(myList, 2):
> ...     print a, b
> ...
> 0 1
> 2 3
> 4 5
> 6 7
> 8 9
> 10 11
> >>>
>
> Jeffrey

This works great except you lose any 'remainder' from myList:

>>> list(groupn(range(10),3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]  # did not include (9,)

The following might be more complex than necessary but it solves the
problem, and like groupn()
it works on infinite lists.

from itertools import groupby, imap
def chunk(it, n=0):
    if n == 0:
        return iter([it])
    grouped = groupby(enumerate(it), lambda x: int(x[0]/n))
    counted = imap(lambda x:x[1], grouped)
    return imap(lambda x: imap(lambda y: y[1], x), counted)

>>> [list(x) for x in chunk(range(10), 3)]
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

Note the chunks are iterators, not tuples as in groupn():

>>> [x for x in chunk(range(10), 3)]
[<itertools.imap object at 0xb78d4c4c>,
 <itertools.imap object at 0xb78d806c>,
 <itertools.imap object at 0xb78d808c>,
 <itertools.imap object at 0xb78d4c6c>]


-- Wade Leftwich
Ithaca, NY




More information about the Python-list mailing list