From: Ulrich Eckhardt on
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
On Tue, May 11, 2010 at 12:09 AM, Ulrich Eckhardt
<eckhardt(a)satorlaser.com> 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
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
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