473,508 Members | 2,074 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

iterating "by twos"

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.
Jul 29 '08 #1
13 1442
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
Something like this may be fast enough:
>>from itertools import izip
xpartition = 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
On Jul 29, 1:36*pm, kj <so...@987jk.com.invalidwrote:
Is there a special pythonic idiom for iterating over a list (or
tuple) two elements at a time?
I use this one a lot:

for x, y in zip(a, a[1:]):
frob(x, y)

Geoff G-T

Jul 29 '08 #4
kj <so...@987jk.com.invalidwrote:
Is there a special pythonic idiom for iterating over a list (or
tuple) two elements at a time?
I don't know of one, and I shouldn't be answering, but the following
should work:

def gulp_two(items):
for i,j in zip(items[0::2], items[1::2]):
yield (i,j)

Let's see...
>>list(gulp_two(range(10)))
[(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)]

Okay, it works.

-Wm
Jul 29 '08 #5
On Jul 29, 2:36*pm, gil...@gmail.com wrote:
On Jul 29, 1:36*pm, kj <so...@987jk.com.invalidwrote:
Is there a special pythonic idiom for iterating over a list (or
tuple) two elements at a time?

* * *I use this one a lot:

for x, y in zip(a, a[1:]):
* * frob(x, y)

Geoff G-T
Whoops, I misread the original post. That would be:

for x, y in zip(a[::2], a[1::2]):
frob(x, y)

... which I don't use a lot.
>>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
gi****@gmail.com wrote:
On Jul 29, 1:36 pm, kj <so...@987jk.com.invalidwrote:
>Is there a special pythonic idiom for iterating over a list (or
tuple) 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
kj


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


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
kj
In <ma************************************@python.org Terry Reedy <tj*****@udel.eduwrites:
>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.
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
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 <so***@987jk.com.invalidwrote:
>
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
On Jul 29, 4:11*pm, Erik Max Francis <m...@alcyone.comwrote:
gil...@gmail.com wrote:
for x, y in zip(a, a[1:]):
* * frob(x, y)

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.
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
On Jul 29, 10:36*am, kj <so...@987jk.com.invalidwrote:
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.
This avoids unnecessary copies of the slice approaches, it does,
however, not include the tail values if the length of iterable isn't
evenly divisible by 'size'.

def groups(iterable, size=2):
return itertools.izip(*[iter(iterable)]*size)

print list(groups(xrange(5)))

[(0, 1), (1, 2), (3, 4)]

--Shahms
Aug 7 '08 #13
On Jul 29, 3:38*pm, Terry Reedy <tjre...@udel.eduwrote:
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.
We note that three distinct methods of the mapping type protocol
support default, -or this if not found-, argument passing.

a.get(k[, x]) a[k] if k in a, else x (4)
a.setdefault(k[, x]) a[k] if k in a, else x (also setting it) (5)
a.pop(k[, x]) a[k] if k in a, else x (and remove k) (8)

You can knock off two of them with a default value:

itertools.igroup( iterable, groupsize[, dummy] )

Observe this overlap from the string type.

find( sub[, start[, end]])
Return the lowest index in the string where substring sub is
found, ...
-1 if sub is not found.
index( sub[, start[, end]])
Like find(), but raise ValueError when the substring is not
found.

Include two grouper functions, one that drops (or fills if 'dummy'
provided), one that returns (or fills if 'dummy' provided).

Or, include two grouper functions, one that drops (or fills), one that
raises ValueError exception, including the partial group as an
attribute of the exception.

If filling with 'None' is your concern, just use a special flag:

_special= object( )
iterb= itertools.grouper( itera, 2, _special )
Aug 7 '08 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

23
5641
by: ian justice | last post by:
Before i post actual code, as i need a speedyish reply. Can i first ask if anyone knows off the top of their head, if there is a likely obvious cause to the following problem. For the moment i've...
12
3709
by: Mikito Harakiri | last post by:
I wonder if WITH RECURSIVE MaryAncestor(anc,desc) AS ( (SELECT parent as anc, child as desc FROM ParentOf WHERE desc = "Mary") UNION (SELECT A1.anc, A2.desc FROM MaryAncestor A1, MaryAncestor...
3
1753
by: EYIII | last post by:
Is it possible to retrieve the "created by" identity and "modified by" identity for a file (e.g. word doc, .pdf, report, etc) using .NET?
15
1871
by: wizofaus | last post by:
I have a chunk of code which is essentially IDbCommand cmd = db.CreateCommand(); cmd.CommandText = "SELECT X, Y, Count(*) FROM Foo WHERE Z = 1 GROUP BY X, Y"; using (IDataReader reader =...
0
7225
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7124
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7326
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
7046
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7498
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5629
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
3195
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
1
766
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
418
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.