The Python Oracle

Iterating over every two elements in a list

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Track title: CC O Beethoven - Piano Sonata No 3 in C

--

Chapters
00:00 Question
00:26 Accepted answer (Score 321)
01:47 Answer 2 (Score 266)
02:19 Answer 3 (Score 96)
02:33 Answer 4 (Score 78)
02:47 Thank you

--

Full question
https://stackoverflow.com/questions/5389...

Accepted answer links:
[izip]: https://docs.python.org/2/library/iterto...
[zip()]: https://docs.python.org/3/library/functi...
[martineau]: https://stackoverflow.com/users/355230/m...
[his answer]: https://stackoverflow.com/questions/4356...
[my question]: https://stackoverflow.com/q/4356329/7884...
[pairwise]: https://docs.python.org/3/library/iterto...
[itertools]: https://docs.python.org/3/library/iterto...
[@lazyr]: https://stackoverflow.com/users/566644/l...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #list

#avk47



ACCEPTED ANSWER

Score 345


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

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

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

Or, more generally:

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

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

In Python 2, you should import izip as a replacement for Python 3's built-in zip() function.

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-1), (sn,sn+1,sn+2,...s2n-1), ..."""
    return zip(*[iter(iterable)] * n)



ANSWER 2

Score 281


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)

Where:

  • 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.



ANSWER 3

Score 101


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

>>> zip(l,l[1:])
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]

>>> zip(l,l[1:])[::2]
[(1, 2), (3, 4), (5, 6)]

>>> [a+b for a,b in zip(l,l[1:])[::2]]
[3, 7, 11]

>>> ["%d + %d = %d" % (a,b,a+b) for a,b in zip(l,l[1:])[::2]]
['1 + 2 = 3', '3 + 4 = 7', '5 + 6 = 11']



ANSWER 4

Score 78


A simple solution.

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

for i in range(0, len(l), 2):
    print str(l[i]), '+', str(l[i + 1]), '=', str(l[i] + l[i + 1])