python
programming
list-iteration
algorithms
code-duplicate

Iterating over every two elements in a list

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Iterating over a list two items at a time is a small pattern, but the best implementation depends on what "two at a time" means in your code. Sometimes you want non-overlapping pairs such as (a, b), (c, d). Sometimes you want a sliding window such as (a, b), (b, c), (c, d). Python can express both cleanly once you choose the behavior you actually need.

Non-Overlapping Pairs with Indexing

If you want pairs of items without overlap, stepping through the list by 2 is clear and explicit:

python
1values = [10, 20, 30, 40, 50, 60]
2
3for i in range(0, len(values), 2):
4    pair = values[i:i + 2]
5    print(pair)

Output:

text
[10, 20]
[30, 40]
[50, 60]

This version is easy to read and handles an odd-length list gracefully. If the list has an odd number of elements, the final slice will contain one item instead of two.

That makes it a good default when incomplete last groups are acceptable.

Pairing with an Iterator

If you specifically want full two-element groups and are comfortable working with tuples, an iterator-based approach is compact:

python
1values = [10, 20, 30, 40, 50, 60]
2it = iter(values)
3
4for a, b in zip(it, it):
5    print(a, b)

Output:

text
10 20
30 40
50 60

This works because zip(it, it) pulls from the same iterator twice, consuming two elements per loop. It is elegant, but it silently drops the final element when the list length is odd.

That behavior is fine when incomplete pairs should be ignored, but it can be a bug when the last item matters.

Preserve the Final Odd Element

If you need to keep the last item even when there is no partner for it, use itertools.zip_longest:

python
1from itertools import zip_longest
2
3values = [10, 20, 30, 40, 50]
4it = iter(values)
5
6for a, b in zip_longest(it, it, fillvalue=None):
7    print(a, b)

Output:

text
10 20
30 40
50 None

This version makes the odd tail explicit instead of losing it.

Sliding Pairs Are a Different Problem

Sometimes "every two elements" really means adjacent overlapping pairs. In that case, do not step by 2:

python
1values = [10, 20, 30, 40]
2
3for i in range(len(values) - 1):
4    print(values[i], values[i + 1])

Output:

text
10 20
20 30
30 40

This pattern is common in algorithms that compare neighbors, compute deltas, or scan text tokens two at a time.

Choose Based on Intent, Not Cleverness

For most production code, the index-based version is the easiest for another developer to understand quickly. The iterator-based zip(it, it) idiom is perfectly valid, but it is slightly more "Pythonic trick" than "obvious control flow." That tradeoff matters more than micro-performance in most applications.

If the code will be read by beginners or appears only once, the simplest loop is often the best loop. If the code is performance-sensitive and the semantics are well understood, iterator-based grouping can be concise and efficient.

Common Pitfalls

  • Using zip(it, it) without realizing it drops the final odd element.
  • Using range(0, len(values), 2) when the real need is overlapping adjacent pairs.
  • Returning slices when the caller expects fixed-size tuples.
  • Writing overly clever one-liners for a simple grouping task.
  • Forgetting to define what should happen when the list length is odd.

Summary

  • Use range(0, len(values), 2) plus slicing when you want clear non-overlapping groups.
  • Use zip(it, it) when you want concise full pairs and can ignore an odd leftover item.
  • Use zip_longest when the last unmatched item should be preserved explicitly.
  • Use a standard index loop for overlapping adjacent pairs.
  • Decide the behavior for odd-length lists first, because that choice drives the right implementation.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.