Python
Programming
Algorithms
List Manipulation
Maximum Value

How to find all positions of the maximum value in a list?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Finding every position of the maximum value is a small problem that still exposes a common mistake: list.index only returns the first match. A correct solution needs to handle duplicates, define behavior for empty input, and stay readable enough that the intent is obvious.

The Clear Two-Step Solution

For an ordinary Python list, the clearest approach is to compute the maximum once and then collect all indices where the value matches that maximum.

python
1values = [5, 9, 2, 9, 3, 9]
2max_value = max(values)
3positions = [i for i, v in enumerate(values) if v == max_value]
4
5print(max_value)
6print(positions)

Output:

text
9
[1, 3, 5]

This solution is readable and fast enough for most real code.

Why list.index Is Not Enough

A lot of people reach for this:

python
values.index(max(values))

That only returns the first matching index. It answers "where is one maximum" instead of "where are all maxima." For unique maxima, that may be fine. For duplicated maxima, it is incomplete.

Handle Empty Input Deliberately

max([]) raises ValueError, so a real helper should define what happens for an empty list. A common policy is to return an empty list.

python
1from typing import Iterable
2
3
4def max_positions(values: Iterable[int]) -> list[int]:
5    data = list(values)
6    if not data:
7        return []
8
9    m = max(data)
10    return [i for i, v in enumerate(data) if v == m]
11
12print(max_positions([1, 4, 4, 2]))
13print(max_positions([]))

That is not the only valid policy. Some codebases prefer to raise on empty input because "no maximum exists" is itself an error. The important part is to choose deliberately.

One-Pass Version for Streams

If the input is very large or cannot be traversed twice, use a one-pass approach.

python
1def max_positions_one_pass(values):
2    max_value = None
3    positions = []
4
5    for index, value in enumerate(values):
6        if max_value is None or value > max_value:
7            max_value = value
8            positions = [index]
9        elif value == max_value:
10            positions.append(index)
11
12    return positions
13
14print(max_positions_one_pass([5, 9, 2, 9, 3, 9]))

This avoids calling max and then iterating again, which is useful for generators or large streams.

Return the Maximum Value Too When Helpful

Often the caller needs both the maximum value and all of its positions. Returning both can make downstream code simpler.

python
1def max_value_and_positions(values):
2    if not values:
3        return None, []
4
5    m = max(values)
6    idxs = [i for i, x in enumerate(values) if x == m]
7    return m, idxs
8
9print(max_value_and_positions([2, 7, 7, 1]))

That avoids recalculating the maximum in the caller.

NumPy and Pandas Versions

If the data already lives in NumPy or pandas, use tools from that ecosystem instead of converting back to plain lists.

python
1import numpy as np
2
3arr = np.array([5, 9, 2, 9, 3, 9])
4positions = np.where(arr == arr.max())[0]
5print(positions.tolist())
python
1import pandas as pd
2
3df = pd.DataFrame({"score": [5, 9, 2, 9, 3, 9]})
4positions = df.index[df["score"] == df["score"].max()].tolist()
5print(positions)

This keeps the code aligned with the structure that already holds the data.

Common Pitfalls

A common mistake is using list.index and assuming it finds every matching position. It only finds the first one.

Another issue is forgetting to define behavior for empty input. That turns a tiny helper into a hidden runtime exception.

Developers also sometimes recompute the maximum inside a loop, which is needlessly expensive and less readable than calculating it once.

Summary

  • Use max plus enumerate for the clearest all-positions solution.
  • 'list.index is not enough when the maximum value appears more than once.'
  • Decide explicitly how empty input should behave.
  • Use a one-pass solution when the input should not be traversed twice.
  • Stick with NumPy or pandas helpers when the data already lives there.

Course illustration
Course illustration

All Rights Reserved.