472,364 Members | 1,775 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,364 software developers and data experts.

Iterate through list two items at a time

Hi all,
I'm looking for a way to iterate through a list, two (or more) items at a
time. Basically...

myList = [1,2,3,4,5,6]

I'd like to be able to pull out two items at a time - simple examples would
be:
Create this output:
1 2
3 4
5 6

Create this list:
[(1,2), (3,4), (5,6)]

I want the following syntax to work, but sadly it does not:
for x,y in myList:
print x, y

I can do this with a simple foreach statement in tcl, and if it's easy in
tcl it's probably not too hard in Python.

Thanks,
Dave
Jan 3 '07 #1
12 19884
On Jan 2, 7:57 pm, "Dave Dean" <dave.d...@xilinx.comwrote:
Hi all,
I'm looking for a way to iterate through a list, two (or more) items at a
time. Basically...

myList = [1,2,3,4,5,6]

I'd like to be able to pull out two items at a time...
def pair_list(list_):
return[list_[i:i+2] for i in xrange(0, len(list_), 2)]

Jan 3 '07 #2
Few alternative solutions (other are possible), I usually use a variant
of the first version, inside a partition function, the second variant
is shorter when you don't have a handy partition() function and you
don't want to import modules, and the forth one needs less memory when
the data is very long:

from itertools import izip, islice

data = [1,2,3,4,5,6,7]

for x1, x2 in (data[i:i+2] for i in xrange(0, len(data)/2*2, 2)):
print x1, x2

for x1, x2 in zip(data[::2], data[1::2]):
print x1, x2

for x1, x2 in izip(data[::2], data[1::2]):
print x1, x2

for x1, x2 in izip(islice(data,0,None,2), islice(data,1,None,2)):
print x1, x2

Bye,
bearophile

Jan 3 '07 #3
>I'm looking for a way to iterate through a list, two (or more) items
at a time. Basically...

myList = [1,2,3,4,5,6]

I'd like to be able to pull out two items at a time...
Dandef pair_list(list_):
Dan return[list_[i:i+2] for i in xrange(0, len(list_), 2)]

Here's another way (seems a bit clearer to me, but each person has their own
way of seeing things):
>>import string
string.letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW XYZ'
>>zip(string.letters[::2], string.letters[1::2])
[('a', 'b'), ('c', 'd'), ..., ('W', 'X'), ('Y', 'Z')]

It extends readily to longer groupings:
>>zip(string.letters[::3], string.letters[1::3], string.letters[2::3])
[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i'), ...

Obviously, if your lists are long, you can substitute itertools.izip for
zip. There's probably some easy way to achieve the same result with
itertools.groupby, but I'm out of my experience there...

Skip
Jan 3 '07 #4
At Tuesday 2/1/2007 22:57, Dave Dean wrote:
myList = [1,2,3,4,5,6]

I'd like to be able to pull out two items at a time - simple examples would
be:
Create this output:
1 2
3 4
5 6
b=iter(a)
for x in b:
y=b.next()
print x,y

b=iter(a)
for x,y in ((item, b.next()) for item in b):
print x,y
>Create this list:
[(1,2), (3,4), (5,6)]
b=iter(a)
[(item, b.next()) for item in b]

Note that they don't behave the same at the corner cases (empty list,
single item, odd length...)
--
Gabriel Genellina
Softlab SRL


__________________________________________________
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
¡Probalo ya!
http://www.yahoo.com.ar/respuestas

Jan 3 '07 #5
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
Jan 3 '07 #6
Thanks for all the fast responses. I'm particularly a fan of the zip
method, followed closely by the xrange example. All, of course, are a lot
of help!
Thanks,
Dave
Jan 3 '07 #7

Dave Dean wrote:
Hi all,
I'm looking for a way to iterate through a list, two (or more) items at a
time. Basically...

myList = [1,2,3,4,5,6]

I'd like to be able to pull out two items at a time - simple examples would
be:
Create this output:
1 2
3 4
5 6

Create this list:
[(1,2), (3,4), (5,6)]
A "padding generator" version:

def chunk( seq, size, pad=None ):
'''
Slice a list into consecutive disjoint 'chunks' of
length equal to size. The last chunk is padded if necessary.
>>list(chunk(range(1,10),3))
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>list(chunk(range(1,9),3))
[[1, 2, 3], [4, 5, 6], [7, 8, None]]
>>list(chunk(range(1,8),3))
[[1, 2, 3], [4, 5, 6], [7, None, None]]
>>list(chunk(range(1,10),1))
[[1], [2], [3], [4], [5], [6], [7], [8], [9]]
>>list(chunk(range(1,10),9))
[[1, 2, 3, 4, 5, 6, 7, 8, 9]]
>>for X in chunk([],3): print X
'''
n = len(seq)
mod = n % size
for i in xrange(0, n-mod, size):
yield seq[i:i+size]
if mod:
padding = [pad] * (size-mod)
yield seq[-mod:] + padding

------------------------------------------------------------------

Gerard

Jan 3 '07 #8
Gabriel Genellina wrote:
b=iter(a)
for x in b:
y=b.next()
print x,y
So as not to choke on odd-length lists, you could try

a = [1,2,3,4,5,6,7]
b = iter(a)
for x in b:
try:
y=b.next()
except StopIteration:
y=None
print x,y

Substitute in whatever for y=None that you like.

Cheers,
Cliff
Jan 3 '07 #9

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

Jan 4 '07 #10

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>]

Jan 4 '07 #11
Wade Leftwich wrote:
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>]
Note that all but the last of these generators are useless:
>>chunks = [x for x in chunk(range(10), 3)]
[list(x) for x in chunks]
[[], [], [], [9]] # did you expect that?

Peter
Jan 4 '07 #12
Peter Otten wrote:
Wade Leftwich wrote:
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>]

Note that all but the last of these generators are useless:
>chunks = [x for x in chunk(range(10), 3)]
[list(x) for x in chunks]
[[], [], [], [9]] # did you expect that?
In [48]: chunkgen = chunk(range(10), 3)
In [49]: for x in chunkgen:
....: print list(x)
....:
....:
[0, 1, 2]
[3, 4, 5]
[6, 7, 8]
[9]
Peter
That's an interesting gotcha that I've never run into when using this
function, because in practice I never put the generator returned by
chunk() inside a list comprehension.

In [51]: chunkgen = chunk(range(10), 3)

In [52]:[list(x) for x in chunkgen]
Out[52]: [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

But, as you pointed out --

In [57]: chunkgen = chunk(range(10), 3)

In [58]: chunks = list(chunkgen)

In [59]:[list(x) for x in chunks]
Out[59]: [[], [], [], [9]]

So apparently when we list(chunkgen), we are exhausting the generators
that are its members. And if we do it again, we get rid of the [9] --

In [60]:[list(x) for x in chunks]
Out[60]: [[], [], [], []]

I'll admit that chunk() is needlessly tricky for most purposes. I wrote
it to accept a really lengthy, possibly unbounded, iterator and write
out 10,000-line files from it, and also to play with Python's new
functional capabilities.

-- Wade

Jan 4 '07 #13

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

Similar topics

4
by: Derek Basch | last post by:
Hello, Can anyone point me towards an article or explain how to properly alter a list as well as iterate on its items? For example: input: word =
3
by: jason | last post by:
How does one loop through the contents of a form complicated by dynamic construction of checkboxes which are assigned a 'model' and 'listingID' to the NAME field on the fly in this syntax:...
2
by: Yoshitha | last post by:
hi I have 2 drop down lists in my application.1st list ontains itmes like java,jsp,swings,vb.net etc.2nd list contains percentage i.e it conatains the items like 50,60,70,80,90,100. i will...
2
by: COHENMARVIN | last post by:
I've been doing a simple for-each loop to remove multiple selected items from one listbox, and to dump them in another listbox. for each item in LeftListBox.Items if (item.Selected = true) Then...
2
by: nickheppleston | last post by:
I'm trying to iterate through repeating elements to extract data using libxml2 but I'm having zero luck - any help would be appreciated. My XML source is similar to the following - I'm trying to...
28
by: John Salerno | last post by:
What is the best way of altering something (in my case, a file) while you are iterating over it? I've tried this before by accident and got an error, naturally. I'm trying to read the lines of a...
7
by: Jacob JKW | last post by:
I need to iterate over combinations of n array elements taken r at a time. Because the value of r may vary quite a bit between program invocations, I'd like to avoid simply hardcoding r loops. I...
2
by: Noah | last post by:
What is the fastest way to select N items at a time from a dictionary? I'm iterating over a dictionary of many thousands of items. I want to operate on only 100 items at a time. I want to avoid...
3
by: Tyro | last post by:
I have built a database that is updated daily with new items. Each new item needs to be given to someone on our team to work on. I would like to automatically assign the new items to the team...
2
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and efficiency. While initially associated with cryptocurrencies...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge required to effectively administer and manage Oracle...
0
by: Arjunsri | last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and credentials and received a successful connection...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific technical details, Gmail likely implements measures...
1
by: Matthew3360 | last post by:
Hi, I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web server and have made sure to enable curl. I get a...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand. Background colors can be used to highlight important...
0
by: Rahul1995seven | last post by:
Introduction: In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python has gained popularity among beginners and experts...
1
by: Johno34 | last post by:
I have this click event on my form. It speaks to a Datasheet Subform Private Sub Command260_Click() Dim r As DAO.Recordset Set r = Form_frmABCD.Form.RecordsetClone r.MoveFirst Do If...
1
by: ezappsrUS | last post by:
Hi, I wonder if someone knows where I am going wrong below. I have a continuous form and two labels where only one would be visible depending on the checkbox being checked or not. Below is the...

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.