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.
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:
Output:
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:
Output:
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:
Output:
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:
Output:
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_longestwhen 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
- Iterating through dictionary with ForEach
- Iterative deepening vs depth-first search
- Iterative depth-first tree traversal with pre- and post-visit at each node
- Iterative DFS vs Recursive DFS and different elements order
- Iterating Through a Dictionary in Swift
- Iterating through a list in reverse order in java
- Iterating over tf.Tensor is not allowed AutoGraph is disabled in this function
- Iterating through a range of dates in Python

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