From: Ulrich Eckhardt on 11 May 2010 03:09 Hi! I have a list [1,2,3,4,5,6] which I'd like to iterate as (1,2), (3,4), (5,6). I can of course roll my own, but I was wondering if there was already some existing library function that already does this. def as_pairs(seq): i = iter(seq) yield (i.next(), i.next()) Question to this code: Is the order of the "i.next()" calls guaranteed to be from left to right? Or could I end up with pairs being switched? Thanks! Uli -- Sator Laser GmbH Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932 From: Chris Rebert on 11 May 2010 03:33 On Tue, May 11, 2010 at 12:09 AM, Ulrich Eckhardt wrote:> Hi! > > I have a list [1,2,3,4,5,6] which I'd like to iterate as (1,2), (3,4), > (5,6). I can of course roll my own, but I was wondering if there was > already some existing library function that already does this. When a problem involves iteration, always check the `itertools` module in the std lib.>From the module docs's recipe section (http://docs.python.org/library/itertools.html#recipes): import itertools def grouper(n, iterable, fillvalue=None): "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" args = [iter(iterable)] * n return itertools.izip_longest(fillvalue=fillvalue, *args) >>> # Let's try it out. >>> list(grouper(2, [1,2,3,4,5,6])) [(1, 2), (3, 4), (5, 6)]>>> # Success! > def as_pairs(seq): > Â  Â i = iter(seq) > Â  Â yield (i.next(), i.next()) > > Question to this code: Is the order of the "i.next()" calls guaranteed to be > from left to right? Or could I end up with pairs being switched? Pretty sure left-to-right is guaranteed; see http://bugs.python.org/issue448679 Also, if you're using Python 2.6+, the line should be: yield (next(i), next(i)) See http://docs.python.org/library/functions.html#next Cheers, Chris -- http://blog.rebertia.com From: Bruno Desthuilliers on 11 May 2010 04:05 Ulrich Eckhardt a écrit :> Hi! > > I have a list [1,2,3,4,5,6] which I'd like to iterate as (1,2), (3,4), > (5,6). I can of course roll my own, but I was wondering if there was > already some existing library function that already does this. >>> l = range(10) >>> for x, y in zip(l[::2], l[1::2]): .... print x, y .... 0 1 2 3 4 5 6 7 8 9 SimplestThingThatCouldPossiblyWork(tm) - but might not be the most efficient idiom, specially with large lists... From: Ulrich Eckhardt on 11 May 2010 04:43 Ulrich Eckhardt wrote:> I have a list [1,2,3,4,5,6] which I'd like to iterate as (1,2), (3,4), > (5,6). I can of course roll my own, but I was wondering if there was > already some existing library function that already does this. > > > def as_pairs(seq): > i = iter(seq) > yield (i.next(), i.next()) Obviously this code does _not_ do what I want, it must be like this: def as_pairs(seq): i = iter(seq) while True: yield (i.next(), i.next()) Gah! Uli -- Sator Laser GmbH Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932  |