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)
```

Output:

```
1+2=3
3+4=7
5+6=11
```

## Solution 1

You need a ** pairwise()** (or

**) implementation.**

`grouped()`

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

**documentation, which yields**

`itertools`

`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)
```

## Solution 2

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.

## Solution 3

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

## Solution 4

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

## Solution 5

While all the answers using `zip`

are correct, I find that implementing the functionality yourself leads to more readable code:

```
def pairwise(it):
it = iter(it)
while True:
try:
yield next(it), next(it)
except StopIteration:
# no more elements in the iterator
return
```

The `it = iter(it)`

part ensures that `it`

is actually an iterator, not just an iterable. If `it`

already is an iterator, this line is a no-op.

Usage:

```
for a, b in pairwise([0, 1, 2, 3, 4, 5]):
print(a + b)
```

## Solution 6

I hope this will be even more elegant way of doing it.

```
a = [1,2,3,4,5,6]
zip(a[::2], a[1::2])
[(1, 2), (3, 4), (5, 6)]
```

## Solution 7

In case you're interested in the performance, I did a small benchmark (using my library `simple_benchmark`

) to compare the performance of the solutions and I included a function from one of my packages: `iteration_utilities.grouper`

```
from iteration_utilities import grouper
import matplotlib as mpl
from simple_benchmark import BenchmarkBuilder
bench = BenchmarkBuilder()
@bench.add_function()
def Johnsyweb(l):
def pairwise(iterable):
"s -> (s0, s1), (s2, s3), (s4, s5), ..."
a = iter(iterable)
return zip(a, a)
for x, y in pairwise(l):
pass
@bench.add_function()
def Margus(data):
for i, k in zip(data[0::2], data[1::2]):
pass
@bench.add_function()
def pyanon(l):
list(zip(l,l[1:]))[::2]
@bench.add_function()
def taskinoor(l):
for i in range(0, len(l), 2):
l[i], l[i+1]
@bench.add_function()
def mic_e(it):
def pairwise(it):
it = iter(it)
while True:
try:
yield next(it), next(it)
except StopIteration:
return
for a, b in pairwise(it):
pass
@bench.add_function()
def MSeifert(it):
for item1, item2 in grouper(it, 2):
pass
bench.use_random_lists_as_arguments(sizes=[2**i for i in range(1, 20)])
benchmark_result = bench.run()
mpl.rcParams['figure.figsize'] = (8, 10)
benchmark_result.plot_both(relative_to=MSeifert)
```

So if you want the fastest solution without external dependencies you probably should just use the approach given by Johnysweb (at the time of writing it's the most upvoted and accepted answer).

If you don't mind the additional dependency then the `grouper`

from `iteration_utilities`

will probably be a bit faster.

## Additional thoughts

Some of the approaches have some restrictions, that haven't been discussed here.

For example a few solutions only work for sequences (that is lists, strings, etc.), for example Margus/pyanon/taskinoor solutions which uses indexing while other solutions work on any iterable (that is sequences **and** generators, iterators) like Johnysweb/mic_e/my solutions.

Then Johnysweb also provided a solution that works for other sizes than 2 while the other answers don't (okay, the `iteration_utilities.grouper`

also allows setting the number of elements to "group").

Then there is also the question about what should happen if there is an odd number of elements in the list. Should the remaining item be dismissed? Should the list be padded to make it even sized? Should the remaining item be returned as single? The other answer don't address this point directly, however if I haven't overlooked anything they all follow the approach that the remaining item should be dismissed (except for taskinoors answer - that will actually raise an Exception).

With `grouper`

you can decide what you want to do:

```
>>> from iteration_utilities import grouper
>>> list(grouper([1, 2, 3], 2)) # as single
[(1, 2), (3,)]
>>> list(grouper([1, 2, 3], 2, truncate=True)) # ignored
[(1, 2)]
>>> list(grouper([1, 2, 3], 2, fillvalue=None)) # padded
[(1, 2), (3, None)]
```

## Solution 8

Use the `zip`

and `iter`

commands together:

I find this solution using `iter`

to be quite elegant:

```
it = iter(l)
list(zip(it, it))
# [(1, 2), (3, 4), (5, 6)]
```

Which I found in the Python 3 zip documentation.

```
it = iter(l)
print(*(f'{u} + {v} = {u+v}' for u, v in zip(it, it)), sep='\n')
# 1 + 2 = 3
# 3 + 4 = 7
# 5 + 6 = 11
```

To generalise to `N`

elements at a time:

```
N = 2
list(zip(*([iter(l)] * N)))
# [(1, 2), (3, 4), (5, 6)]
```

## Solution 9

```
for (i, k) in zip(l[::2], l[1::2]):
print i, "+", k, "=", i+k
```

`zip(*iterable)`

returns a tuple with the next element of each iterable.

`l[::2]`

returns the 1st, the 3rd, the 5th, etc. element of the list: the first colon indicates that the slice starts at the beginning because there's no number behind it, the second colon is only needed if you want a 'step in the slice' (in this case 2).

`l[1::2]`

does the same thing but starts in the second element of the lists so it returns the 2nd, the 4th, 6th, etc. element of the **original** list.

## Solution 10

With unpacking:

```
l = [1,2,3,4,5,6]
while l:
i, k, *l = l
print(f'{i}+{k}={i+k}')
```

Note: this will consume `l`

, leaving it empty afterward.

## Solution 11

There are many ways to do that. For example:

```
lst = [1,2,3,4,5,6]
[(lst[i], lst[i+1]) for i,_ in enumerate(lst[:-1])]
>>>[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
[i for i in zip(*[iter(lst)]*2)]
>>>[(1, 2), (3, 4), (5, 6)]
```

## Solution 12

you can use more_itertools package.

```
import more_itertools
lst = range(1, 7)
for i, j in more_itertools.chunked(lst, 2):
print(f'{i} + {j} = {i+j}')
```

## Solution 13

For anyone it might help, here is a solution to a similar problem but with overlapping pairs (instead of mutually exclusive pairs).

From the Python itertools documentation:

```
from itertools import izip
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
```

Or, more generally:

```
from itertools import izip
def groupwise(iterable, n=2):
"s -> (s0,s1,...,sn-1), (s1,s2,...,sn), (s2,s3,...,sn+1), ..."
t = tee(iterable, n)
for i in range(1, n):
for j in range(0, i):
next(t[i], None)
return izip(*t)
```

## Solution 14

The title of this question is misleading, you seem to be looking for consecutive pairs, but if you want to iterate over the set of all possible pairs than this will work :

```
for i,v in enumerate(items[:-1]):
for u in items[i+1:]:
```

## Solution 15

A simplistic approach:

```
[(a[i],a[i+1]) for i in range(0,len(a),2)]
```

this is useful if your array is a and you want to iterate on it by pairs. To iterate on triplets or more just change the "range" step command, for example:

```
[(a[i],a[i+1],a[i+2]) for i in range(0,len(a),3)]
```

(you have to deal with excess values if your array length and the step do not fit)

## Solution 16

The polished Python3 solution is given in one of the `itertools`

recipes:

```
import itertools
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return itertools.zip_longest(*args, fillvalue=fillvalue)
```

## Solution 17

Another try at cleaner solution

```
def grouped(itr, n=2):
itr = iter(itr)
end = object()
while True:
vals = tuple(next(itr, end) for _ in range(n))
if vals[-1] is end:
return
yield vals
```

For more customization options

```
from collections.abc import Sized
def grouped(itr, n=2, /, truncate=True, fillvalue=None, strict=False, nofill=False):
if strict:
if isinstance(itr, Sized):
if len(itr) % n != 0:
raise ValueError(f"{len(itr)=} is not divisible by {n=}")
itr = iter(itr)
end = object()
while True:
vals = tuple(next(itr, end) for _ in range(n))
if vals[-1] is end:
if vals[0] is end:
return
if strict:
raise ValueError("found extra stuff in iterable")
if nofill:
yield tuple(v for v in vals if v is not end)
return
if truncate:
return
yield tuple(v if v is not end else fillvalue for v in vals)
return
yield vals
```

## Solution 18

Thought that this is a good place to share my generalization of this for n>2, which is just a sliding window over an iterable:

```
def sliding_window(iterable, n):
its = [ itertools.islice(iter, i, None)
for i, iter
in enumerate(itertools.tee(iterable, n)) ]
return itertools.izip(*its)
```

## Solution 19

I need to divide a list by a number and fixed like this.

```
l = [1,2,3,4,5,6]
def divideByN(data, n):
return [data[i*n : (i+1)*n] for i in range(len(data)//n)]
>>> print(divideByN(l,2))
[[1, 2], [3, 4], [5, 6]]
>>> print(divideByN(l,3))
[[1, 2, 3], [4, 5, 6]]
```

## Solution 20

Using typing so you can verify data using mypy static analysis tool:

```
from typing import Iterator, Any, Iterable, TypeVar, Tuple
T_ = TypeVar('T_')
Pairs_Iter = Iterator[Tuple[T_, T_]]
def legs(iterable: Iterator[T_]) -> Pairs_Iter:
begin = next(iterable)
for end in iterable:
yield begin, end
begin = end
```

## Solution 21

Here we can have `alt_elem`

method which can fit in your for loop.

```
def alt_elem(list, index=2):
for i, elem in enumerate(list, start=1):
if not i % index:
yield tuple(list[i-index:i])
a = range(10)
for index in [2, 3, 4]:
print("With index: {0}".format(index))
for i in alt_elem(a, index):
print(i)
```

Output:

```
With index: 2
(0, 1)
(2, 3)
(4, 5)
(6, 7)
(8, 9)
With index: 3
(0, 1, 2)
(3, 4, 5)
(6, 7, 8)
With index: 4
(0, 1, 2, 3)
(4, 5, 6, 7)
```

Note: Above solution might not be efficient considering operations performed in func.

## Solution 22

This is simple solution, which is using range function to pick alternative elements from a list of elements.

Note: This is only valid for an even numbered list.

```
a_list = [1, 2, 3, 4, 5, 6]
empty_list = []
for i in range(0, len(a_list), 2):
empty_list.append(a_list[i] + a_list[i + 1])
print(empty_list)
# [3, 7, 11]
```