Iterate through list two items at a time
Wade Leftwich
wleftwich at gmail.com
Thu Jan 4 07:33:00 EST 2007
Wade Leftwich wrote:
> 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
Or, using generator expressions instead of imap and getting rid of the
lambdas --
from itertools import groupby
def chunk(it, n=0):
if n == 0:
return iter([it])
def groupfun((x,y)):
return int(x/n)
grouped = groupby(enumerate(it), groupfun)
counted = (y for (x,y) in grouped)
return ((z for (y,z) in x) for x in counted)
>>> [list(x) for x in chunk(range(10), 3)]
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
>>> [x for x in chunk(range(10), 3)]
[<generator object at 0xb7a34e4c>,
<generator object at 0xb7a34dac>,
<generator object at 0xb7a34d2c>,
<generator object at 0xb7a34d6c>]
More information about the Python-list
mailing list