Iterating over every two elements in a list


How do I make a for loop or a list comprehension so that every iteration gives me two elements?

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

for i,k in ???:
    print str(i), '+', str(k), '=', str(i+k)


4/6/2015 7:47:05 PM

Accepted Answer

You need a pairwise() (or grouped()) implementation.

For Python 2:

from itertools import izip

def pairwise(iterable):
    "s -> (s0, s1), (s2, s3), (s4, s5), ..."
    a = iter(iterable)
    return izip(a, a)

for x, y in pairwise(l):
   print "%d + %d = %d" % (x, y, x + y)

Or, more generally:

from itertools import izip

def grouped(iterable, n):
    "s -> (s0,s1,s2,, (sn,sn+1,sn+2,...s2n-1), (s2n,s2n+1,s2n+2,...s3n-1), ..."
    return izip(*[iter(iterable)]*n)

for x, y in grouped(l, 2):
   print "%d + %d = %d" % (x, y, x + y)

In Python 3, you can replace izip with the built-in zip() function, and drop the import.

All credit to martineau for his answer to my question, I have found this to be very efficient as it only iterates once over the list and does not create any unnecessary lists in the process.

N.B: This should not be confused with the pairwise recipe in Python's own itertools documentation, which yields s -> (s0, s1), (s1, s2), (s2, s3), ..., as pointed out by @lazyr in the comments.

Little addition for those who would like to do type checking with mypy on Python 3:

from typing import Iterable, Tuple, TypeVar

T = TypeVar("T")

def grouped(iterable: Iterable[T], n=2) -> Iterable[Tuple[T, ...]]:
    """s -> (s0,s1,s2,, (sn,sn+1,sn+2,...s2n-1), ..."""
    return zip(*[iter(iterable)] * n)
7/9/2019 8:13:57 AM

Well you need tuple of 2 elements, so

data = [1,2,3,4,5,6]
for i,k in zip(data[0::2], data[1::2]):
    print str(i), '+', str(k), '=', str(i+k)


  • data[0::2] means create subset collection of elements that (index % 2 == 0)
  • zip(x,y) creates a tuple collection from x and y collections same index elements.

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow