459,277 Members | 1,433 Online
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,277 IT Pros & Developers. It's quick & easy.

# iterating "by twos"

 P: n/a Is there a special pythonic idiom for iterating over a list (or tuple) two elements at a time? I mean, other than for i in range(0, len(a), 2): frobnicate(a[i], a[i+1]) ? I think I once saw something like for (x, y) in forgotten_expression_using(a): frobnicate(x, y) Or maybe I just dreamt it! :) Thanks! -- NOTE: In my address everything before the first period is backwards; and the last period, and everything after it, should be discarded. Jul 29 '08 #1
13 Replies

 P: n/a kj wrote: Is there a special pythonic idiom for iterating over a list (or tuple) two elements at a time? I mean, other than for i in range(0, len(a), 2): frobnicate(a[i], a[i+1]) ? I think I once saw something like for (x, y) in forgotten_expression_using(a): frobnicate(x, y) Or maybe I just dreamt it! :) Thanks! I saw the same thing, forgot where though. But I put it in my library. Here it is: # x.py import itertools def pairs(seq): is1 = itertools.islice(iter(seq), 0, None, 2) is2 = itertools.islice(iter(seq), 1, None, 2) return itertools.izip(is1, is2) s = range(9) for x, y in pairs(s): print x, y dilbert@trojanpython x.py 0 1 2 3 4 5 6 7 Jul 29 '08 #2

 P: n/a Something like this may be fast enough: >>from itertools import izipxpartition = lambda seq, n=2: izip(*(iter(seq),) * n)xprimes = (x for x in xrange(2, 100) if all(x % i for i in xrange(2, x)))list(xpartition(xprimes)) [(2, 3), (5, 7), (11, 13), (17, 19), (23, 29), (31, 37), (41, 43), (47, 53), (59, 61), (67, 71), (73, 79), (83, 89)] Bye, bearophile Jul 29 '08 #3

 P: n/a On Jul 29, 1:36*pm, kj

 P: n/a kj >list(gulp_two(range(10))) [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)] Okay, it works. -Wm Jul 29 '08 #5

 P: n/a On Jul 29, 2:36*pm, gil...@gmail.com wrote: On Jul 29, 1:36*pm, kj >a = range(9)for x, y in zip(a, a[1:]): ... print x, y ... 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 >>for x, y in zip(a[::2], a[1::2]): ... print x, y ... 0 1 2 3 4 5 6 7 Geoff G-T Jul 29 '08 #6

 P: n/a gi****@gmail.com wrote: On Jul 29, 1:36 pm, kj Is there a special pythonic idiom for iterating over a list (ortuple) two elements at a time? I use this one a lot: for x, y in zip(a, a[1:]): frob(x, y) It doesn't work: >>a = range(10)[(x, y) for x, y in zip(a, a[1:])] [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9)] What you meant was this: >>[(x, y) for x, y in zip(a[::2], a[1::2])] [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)] but this creates three sublists through slicing and zip. The use of islice and izip is better, particularly if the list that's being iterated over is large. -- Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/ San Jose, CA, USA && 37 18 N 121 57 W && AIM, Y!M erikmaxfrancis Tell me the truth / I'll take it like a man -- Chante Moore Jul 29 '08 #7

 P: n/a Thanks for all the replies. I learned a lot! kynn -- NOTE: In my address everything before the first period is backwards; and the last period, and everything after it, should be discarded. Jul 29 '08 #8

 P: n/a kj wrote: Is there a special pythonic idiom for iterating over a list (or tuple) two elements at a time? I mean, other than for i in range(0, len(a), 2): frobnicate(a[i], a[i+1]) There have been requests to add a grouper function to itertools, but its author has resisted because there are at least three things one might do with the short remainder group left over when the group size does not evenly divide the sequence size: drop it, return it, or fill it to the requested groupsize with a dummy value and then return it. Here is a version of the first alternative. def grouper(iterable,n): '''Return items from iterable in groups of n. This version drops incomplete groups. Python 3.0''' it=iter(iterable) ranger = range(n) while True: ret = [] for i in ranger: ret.append(next(it)) yield ret for pair in grouper(range(11),2): print(pair) [0, 1] [2, 3] [4, 5] [6, 7] [8, 9] >>> Jul 29 '08 #9

 P: n/a In kj wrote: >Is there a special pythonic idiom for iterating over a list (ortuple) two elements at a time?I mean, other thanfor i in range(0, len(a), 2): frobnicate(a[i], a[i+1]) >There have been requests to add a grouper function to itertools, but itsauthor has resisted because there are at least three things one might dowith the short remainder group left over when the group size does notevenly divide the sequence size: drop it, return it, or fill it to therequested groupsize with a dummy value and then return it. Why not make this choice a third argument to the grouper function? Kynn -- NOTE: In my address everything before the first period is backwards; and the last period, and everything after it, should be discarded. Jul 29 '08 #10

 P: n/a The following method is similar to the others provided, but yields an index value as well (similar to the enumerate(iterable) function). This is useful in some (but not all) situations. If the iterable object's iterator returns an even number of items then you're fine; otherwise it will throw away the last item because it doesn't have a full pair to return. ------------------------- import itertools def enumeratePairs(x): it = iter(x) for i in itertools.count(): p = it.next() q = it.next() yield i, (p,q) raise StopIteration -------------------------- >>for v in enumeratePairs("hello i am daniel"): .... print v .... (0, ('h', 'e')) (1, ('l', 'l')) (2, ('o', ' ')) (3, ('i', ' ')) (4, ('a', 'm')) (5, (' ', 'd')) (6, ('a', 'n')) (7, ('i', 'e')) ------------------------------- On Tue, Jul 29, 2008 at 1:36 PM, kj Is there a special pythonic idiom for iterating over a list (or tuple) two elements at a time? I mean, other than for i in range(0, len(a), 2): frobnicate(a[i], a[i+1]) ? I think I once saw something like for (x, y) in forgotten_expression_using(a): frobnicate(x, y) Or maybe I just dreamt it! :) Thanks! -- NOTE: In my address everything before the first period is backwards; and the last period, and everything after it, should be discarded. -- http://mail.python.org/mailman/listinfo/python-list Jul 30 '08 #11

 P: n/a On Jul 29, 4:11*pm, Erik Max Francis >[(x, y) for x, y in zip(a[::2], a[1::2])] [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)] but this creates three sublists through slicing and zip. *The use of islice and izip is better, particularly if the list that's being iterated over is large. The lists I use it with are generally pretty small (a few thousand items at most) so I decided to go with simple rather than clever. That said, I use it enough that it should become its own function, at which point I'll probably grab something from this thread. Cheers, Geoff G-T Jul 30 '08 #12

 P: n/a On Jul 29, 10:36*am, kj

 P: n/a On Jul 29, 3:38*pm, Terry Reedy

### This discussion thread is closed

Replies have been disabled for this discussion.