Skip to content

How to Compare Adjacent Elements in a List in Python

How to compare consecutive elements in a Python list using zip(), itertools.pairwise(), loops, and list comprehensions, with examples for finding duplicates, checking order, and analyzing trends.

Comparing adjacent elements in a list means iterating through the list and checking each element against the one that follows it. This is a common operation in many programming tasks, detecting duplicates, finding trends in data, validating sorted order, or identifying transitions between values.

In this guide, you'll learn multiple ways to compare consecutive elements in a Python list, from clean built-in approaches to manual loop-based methods, each with clear examples and outputs.

Using zip() with Slicing

The most Pythonic and readable approach is to use zip() to pair each element with the next one. By zipping the original list with a sliced version of itself (li[1:]), you get clean pairs of adjacent elements.

li = [1, 2, 2, 3, 4, 4, 5]

for current, next_elem in zip(li, li[1:]):
    print(f"{current}, {next_elem} → Equal: {current == next_elem}")

Output:

1, 2 → Equal: False
2, 2 → Equal: True
2, 3 → Equal: False
3, 4 → Equal: False
4, 4 → Equal: True
4, 5 → Equal: False

How it works:

  • li[1:] creates a copy of the list starting from the second element.
  • zip(li, li[1:]) pairs li[0] with li[1], li[1] with li[2], and so on.
  • The loop automatically stops when the shorter iterable (li[1:]) is exhausted.

Using itertools.pairwise() (Python 3.10+)

Starting with Python 3.10, the itertools module provides pairwise(), which is purpose-built for generating consecutive pairs from an iterable. It's memory-efficient because it doesn't create a sliced copy of the list.

from itertools import pairwise

li = [1, 2, 2, 3, 4, 4, 5]

for current, next_elem in pairwise(li):
    print(f"{current}, {next_elem} → Equal: {current == next_elem}")

Output:

1, 2 → Equal: False
2, 2 → Equal: True
2, 3 → Equal: False
3, 4 → Equal: False
4, 4 → Equal: True
4, 5 → Equal: False

Using a For Loop with Index

A traditional for loop with index-based access gives you explicit control over iteration. This is straightforward and works in all Python versions.

li = [1, 2, 2, 3, 4, 4, 5]

for i in range(len(li) - 1):
    current = li[i]
    next_elem = li[i + 1]
    print(f"{current}, {next_elem} → Equal: {current == next_elem}")

Output:

1, 2 → Equal: False
2, 2 → Equal: True
2, 3 → Equal: False
3, 4 → Equal: False
4, 4 → Equal: True
4, 5 → Equal: False

The key detail is range(len(li) - 1), which stops at the second-to-last element to prevent an IndexError when accessing li[i + 1].

Using List Comprehension

If you need to collect all comparison results into a list (rather than printing them one by one), a list comprehension provides a compact one-liner:

li = [1, 2, 2, 3, 4, 4, 5]

results = [(a, b, a == b) for a, b in zip(li, li[1:])]

for current, next_elem, is_equal in results:
    print(f"{current}, {next_elem} → Equal: {is_equal}")

Output:

1, 2 → Equal: False
2, 2 → Equal: True
2, 3 → Equal: False
3, 4 → Equal: False
4, 4 → Equal: True
4, 5 → Equal: False

This approach is useful when you want to store the results for further processing rather than acting on them immediately.

Practical Examples

Finding Duplicate Adjacent Elements

Identify positions where consecutive elements are the same:

li = [1, 2, 2, 3, 4, 4, 4, 5]

duplicates = [i for i in range(len(li) - 1) if li[i] == li[i + 1]]

print(f"Duplicate adjacent pairs at indices: {duplicates}")
for idx in duplicates:
    print(f"  Index {idx}-{idx+1}: {li[idx]} == {li[idx+1]}")

Output:

Duplicate adjacent pairs at indices: [1, 4, 5]
  Index 1-2: 2 == 2
  Index 4-5: 4 == 4
  Index 5-6: 4 == 4

Checking if a List Is Sorted

Compare adjacent elements to verify ascending order:

def is_sorted(li):
    return all(a <= b for a, b in zip(li, li[1:]))

print(is_sorted([1, 2, 3, 4, 5]))
print(is_sorted([1, 3, 2, 4, 5]))

Output:

True
False

The all() function returns True only if every adjacent pair satisfies the condition a <= b.

Calculating Differences Between Consecutive Elements

Compute the change between each pair of adjacent values:

prices = [100, 105, 102, 108, 107, 115]

changes = [b - a for a, b in zip(prices, prices[1:])]

print(f"Prices:  {prices}")
print(f"Changes: {changes}")

Output:

Prices:  [100, 105, 102, 108, 107, 115]
Changes: [5, -3, 6, -1, 8]

Detecting Sign Changes

Find where values transition from positive to negative (or vice versa):

values = [3, 1, -2, -5, 4, 7, -1]

sign_changes = [
    i for i, (a, b) in enumerate(zip(values, values[1:]))
    if (a >= 0) != (b >= 0)
]

print(f"Sign changes at indices: {sign_changes}")
for idx in sign_changes:
    print(f"  {values[idx]} → {values[idx+1]}")

Output:

Sign changes at indices: [1, 3, 5]
  1 → -2
  -5 → 4
  7 → -1

Quick Comparison of Methods

Method Python Version Memory Efficient Readability Best For
zip(li, li[1:]) All versions 🔶 Creates a copy ✅ Excellent General use
itertools.pairwise() 3.10+ ✅ No copy needed ✅ Excellent Large lists, iterators
for loop with index All versions ✅ No copy needed ✅ Good When you need the index
List comprehension All versions 🔶 Creates result list ✅ Good Storing results

Conclusion

Comparing adjacent elements in a list is a fundamental operation with many practical applications. Python offers several clean approaches:

  • zip(li, li[1:]) is the most Pythonic and readable method. Ideal for most situations.
  • itertools.pairwise() is the most memory-efficient option for Python 3.10+ and is perfect for large datasets or generators.
  • Index-based for loops give you direct control and access to element positions when needed.
  • List comprehensions let you collect comparison results compactly for further processing.

For everyday use, zip() with slicing strikes the best balance of clarity and simplicity. For performance-critical code with large iterables, prefer itertools.pairwise().

Navigation