Python
Programming
Lists
Looping
Python-tips

How do I loop through a list by twos?

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

Looping through a list by twos can mean two slightly different things: stepping through indexes in increments of two, or processing adjacent pairs of elements together. The right pattern depends on whether you need indexes, pairs, or graceful handling of odd-length input.

Step by Two with range

If you want list positions 0, 2, 4, and so on, use range with a step of 2.

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

Output:

text
0 10
2 30
4 50

This is the clearest answer when you mean “visit every other element.”

Process Consecutive Pairs

If you want (0, 1), then (2, 3), then (4, 5), step through the indexes and read two elements per loop.

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

Output:

text
10 20
30 40
50 60

This is common when the list stores coordinate pairs, key-value pairs, or start-end ranges.

Handle Odd-Length Lists Safely

The previous pattern assumes the list length is even. If the list may have an unmatched last element, guard against that explicitly.

python
1values = [10, 20, 30, 40, 50]
2
3for i in range(0, len(values), 2):
4    first = values[i]
5    second = values[i + 1] if i + 1 < len(values) else None
6    print(first, second)

This avoids IndexError and makes the rule for the leftover element explicit.

Whether None is the right placeholder depends on the application. In some cases, you may prefer to raise an error instead because an odd number of items is invalid input.

Python 3.12: itertools.batched

If you are using Python 3.12 or newer, itertools.batched is a clean way to group a list into fixed-size chunks.

python
1from itertools import batched
2
3values = [10, 20, 30, 40, 50]
4
5for pair in batched(values, 2):
6    print(pair)

Output:

text
(10, 20)
(30, 40)
(50,)

This is very readable and naturally shows that the last chunk may be shorter.

Older Python: Slice the List in Chunks

If you do not have batched, slicing inside a stepped loop is another good pattern.

python
1values = [10, 20, 30, 40, 50]
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]

This is convenient when you want small sublists rather than separate variables.

Adjacent Overlapping Pairs Are Different

Sometimes people say “by twos” but actually mean overlapping pairs such as (10, 20), (20, 30), (30, 40). That is a different problem.

For overlapping pairs, you do not step by two:

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

Clarifying that difference avoids the wrong loop shape.

Choose the Pattern by Intent

Use:

  • 'range(0, len(values), 2) for every other index'
  • indexed access with i and i + 1 for strict pairs
  • slicing for chunk-style grouping
  • 'itertools.batched when available and you want readable chunking'

The exact loop should express the meaning of the data, not just its mechanics.

Common Pitfalls

The biggest mistake is forgetting that values[i + 1] can fail on odd-length lists.

Another mistake is using a by-two loop when the task actually needs overlapping adjacent pairs. Those are different iterations.

Developers also sometimes overcomplicate this with nested loops or manual counters when range(..., step=2) already expresses the intent directly.

Finally, if the list logically represents fixed-width records, consider whether the data structure itself should be changed so the pairs are already stored as pairs.

Summary

  • Use range(0, len(values), 2) to loop through a list in steps of two.
  • Access values[i] and values[i + 1] when processing strict consecutive pairs.
  • Guard against odd-length input if the final element may be unmatched.
  • 'itertools.batched is a clean modern option for chunking by twos.'
  • Be clear whether you want disjoint pairs or overlapping adjacent pairs, because the loop shape is different.

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.