Python
max function
min function
list indexing
programming tips

Getting the index of the returned max or min item using max/min on a list

Master System Design with Codemia

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

Introduction

Python’s max() and min() return the value, not the position where that value occurred. If you need the index of the largest or smallest item, you have to keep track of positions yourself. The best method depends on whether you want the simplest code or a one-pass solution.

The Simple Two-Step Approach

If you only need the index and the list is not huge, the clearest code is often:

python
1values = [4, 9, 2, 9, 1]
2
3max_value = max(values)
4max_index = values.index(max_value)
5
6print(max_value)   # 9
7print(max_index)   # 1

For the minimum:

python
1min_value = min(values)
2min_index = values.index(min_value)
3
4print(min_value)   # 1
5print(min_index)   # 4

This is easy to read, but it scans the list twice:

  1. once to find the extreme value
  2. once to find its first index

That is completely fine for many everyday cases.

One-Pass Approach With enumerate

If you want the index and value together in one pass, combine enumerate with max or min:

python
1values = [4, 9, 2, 9, 1]
2
3max_index, max_value = max(enumerate(values), key=lambda pair: pair[1])
4min_index, min_value = min(enumerate(values), key=lambda pair: pair[1])
5
6print(max_index, max_value)  # 1 9
7print(min_index, min_value)  # 4 1

enumerate(values) produces pairs of (index, value). The key function tells max or min to compare only the second item in each pair.

This is usually the most useful pattern because it keeps the index and the value synchronized naturally.

Using range With __getitem__

Another compact pattern is to let max operate on indices directly:

python
1values = [4, 9, 2, 9, 1]
2
3max_index = max(range(len(values)), key=values.__getitem__)
4min_index = min(range(len(values)), key=values.__getitem__)
5
6print(max_index)  # 1
7print(min_index)  # 4

This works because range(len(values)) produces indices, and values.__getitem__ tells Python how to look up the value for each index.

It is concise, but many people find the enumerate version easier to understand.

What Happens With Ties

When the maximum or minimum occurs more than once, these methods return the first matching index.

Example:

python
1values = [7, 3, 9, 2, 9]
2
3index, value = max(enumerate(values), key=lambda pair: pair[1])
4print(index, value)  # 2 9

Even though 9 also appears at index 4, max returns the first maximum it encounters.

If you need all indices of the maximum value, compute the value first and then collect matches:

python
1values = [7, 3, 9, 2, 9]
2target = max(values)
3indices = [i for i, value in enumerate(values) if value == target]
4
5print(indices)  # [2, 4]

Empty Lists Need Special Handling

All of these approaches fail on an empty list because there is no maximum or minimum element.

A safe wrapper might look like this:

python
1def index_of_max(values):
2    if not values:
3        return None
4    return max(range(len(values)), key=values.__getitem__)
5
6print(index_of_max([]))  # None

Choose whether None, an exception, or another sentinel makes sense for your application.

Choosing the Best Pattern

Use values.index(max(values)) when:

  • the list is not large
  • clarity matters more than tiny performance differences
  • you only need the first matching index

Use max(enumerate(values), key=...) when:

  • you want index and value together
  • you prefer a one-pass solution
  • you want a reusable pattern for custom comparisons

Common Pitfalls

The biggest pitfall is expecting max(values) to return the index. It never does. It returns the value itself.

Another common issue is forgetting tie behavior. These recipes return the first matching index, not every matching index.

Empty lists also trip people up. max([]) and min([]) raise ValueError, so guard against empty input when necessary.

Finally, avoid over-optimizing too early. The two-pass index(max(values)) approach is perfectly good unless list size or repeated execution actually makes it a bottleneck.

Summary

  • 'max() and min() return values, not indices.'
  • 'values.index(max(values)) is the simplest solution for the first matching index.'
  • 'max(enumerate(values), key=lambda pair: pair[1]) gets index and value together in one pass.'
  • Ties return the first matching index unless you explicitly collect all matches.
  • Handle empty lists explicitly if they are possible in your input.

Course illustration
Course illustration

All Rights Reserved.