How do I loop through a Python list by twos? [duplicate]

0 votes
asked Jun 7, 2010 by froadie

Possible Duplicate:
What is the most “pythonic” way to iterate over a list in chunks?

I want to loop through a Python list and process 2 list items at a time. Something like this in another language:

for(int i = 0; i < list.length(); i+=2)
{
   // do something with list[i] and list[i + 1]
}

What's the best way to accomplish this?

7 Answers

0 votes
answered Jan 7, 2010 by jorenko

If you have control over the structure of the list, the most pythonic thing to do would probably be to change it from:

l=[1,2,3,4]

to:

l=[(1,2),(3,4)]

Then, your loop would be:

for i,j in l:
    print i, j
0 votes
answered Jan 7, 2010 by lambacck

This might not be as fast as the izip_longest solution (I didn't actually test it), but it will work with python < 2.6 (izip_longest was added in 2.6):

from itertools import imap

def grouper(n, iterable):
    "grouper(3, 'ABCDEFG') --> ('A,'B','C'), ('D','E','F'), ('G',None,None)"
    args = [iter(iterable)] * n

    return imap(None, *args)

If you need to go earlier than 2.3, you can substitute the built-in map for imap. The disadvantage is that it provides no ability to customize the fill value.

0 votes
answered Jun 7, 2010 by brian-r-bondy

You can use for in range with a step size of 2:

Python 2

for i in xrange(0,10,2):
  print(i)

Python 3

for i in range(0,10,2):
  print(i)

Note: Use xrange in Python 2 instead of range because it is more efficient as it generates an iterable object, and not the whole list.

0 votes
answered Jun 7, 2010 by mark-byers

If you're using Python 2.6 or newer you can use the grouper recipe from the itertools module:

from itertools import izip_longest

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

Call like this:

for item1, item2 in grouper(2, l):
    # Do something with item1 and item2

Note that in Python 3.x you should use zip_longest instead of izip_longest.

0 votes
answered Jun 7, 2010 by jathanism

You can also use this syntax (L[start:stop:step]):

mylist = [1,2,3,4,5,6,7,8,9,10]
for i in mylist[::2]:
    print i,
# prints 1 3 5 7 9

for i in mylist[1::2]:
    print i,
# prints 2 4 6 8 10

Where the first digit is the starting index (defaults to beginning of list or 0), 2nd is ending slice index (defaults to end of list), and the third digit is the offset or step.

0 votes
answered Jun 7, 2010 by ishpeck
nums = range(10)
for i in range(0, len(nums)-1, 2):
    print nums[i]

Kinda dirty but it works.

0 votes
answered Jun 7, 2010 by carl

The simplest in my opinion is just this:

it = iter([1,2,3,4,5,6])
for x, y in zip(it, it):
    print x, y

No extra imports or anything. And very elegant, in my opinion.

Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...