## The Question :

*526 people think this question is useful*

I’m using Python’s `max`

and `min`

functions on lists for a minimax algorithm, and I need the index of the value returned by `max()`

or `min()`

. In other words, I need to know which move produced the max (at a first player’s turn) or min (second player) value.

for i in range(9):
newBoard = currentBoard.newBoardWithMove([i / 3, i % 3], player)
if newBoard:
temp = minMax(newBoard, depth + 1, not isMinLevel)
values.append(temp)
if isMinLevel:
return min(values)
else:
return max(values)

I need to be able to return the actual index of the min or max value, not just the value.

*The Question Comments :*

## The Answer 1

*470 people think this answer is useful*

if isMinLevel:
return values.index(min(values))
else:
return values.index(max(values))

## The Answer 2

*531 people think this answer is useful*

Say that you have a list `values = [3,6,1,5]`

, and need the index of the smallest element, i.e. `index_min = 2`

in this case.

Avoid the solution with `itemgetter()`

presented in the other answers, and use instead

index_min = min(range(len(values)), key=values.__getitem__)

because it doesn’t require to `import operator`

nor to use `enumerate`

, and it is always faster(benchmark below) than a solution using `itemgetter()`

.

If you are dealing with numpy arrays or can afford `numpy`

as a dependency, consider also using

import numpy as np
index_min = np.argmin(values)

This will be faster than the first solution even if you apply it to a pure Python list if:

- it is larger than a few elements (about 2**4 elements on my machine)
- you can afford the memory copy from a pure list to a
`numpy`

array

as this benchmark points out:

I have run the benchmark on my machine with python 2.7 for the two solutions above (blue: pure python, first solution) (red, numpy solution) and for the standard solution based on `itemgetter()`

(black, reference solution).
The same benchmark with python 3.5 showed that the methods compare exactly the same of the python 2.7 case presented above

## The Answer 3

*346 people think this answer is useful*

You can find the min/max index and value at the same time if you enumerate the items in the list, but perform min/max on the original values of the list. Like so:

import operator
min_index, min_value = min(enumerate(values), key=operator.itemgetter(1))
max_index, max_value = max(enumerate(values), key=operator.itemgetter(1))

This way the list will only be traversed once for min (or max).

## The Answer 4

*123 people think this answer is useful*

If you want to find the index of max within a list of numbers (which seems your case), then I suggest you use numpy:

import numpy as np
ind = np.argmax(mylist)

## The Answer 5

*42 people think this answer is useful*

Possibly a simpler solution would be to turn the array of values into an array of value,index-pairs, and take the max/min of that. This would give the largest/smallest index that has the max/min (i.e. pairs are compared by first comparing the first element, and then comparing the second element if the first ones are the same). Note that it’s not necessary to actually create the array, because min/max allow generators as input.

values = [3,4,5]
(m,i) = max((v,i) for i,v in enumerate(values))
print (m,i) #(5, 2)

## The Answer 6

*30 people think this answer is useful*

list=[1.1412, 4.3453, 5.8709, 0.1314]
list.index(min(list))

Will give you first index of minimum.

## The Answer 7

*21 people think this answer is useful*

I think the best thing to do is convert the list to a `numpy array`

and use this function :

a = np.array(list)
idx = np.argmax(a)

## The Answer 8

*14 people think this answer is useful*

I was also interested in this and compared some of the suggested solutions using perfplot (a pet project of mine).

Turns out that numpy’s argmin,

numpy.argmin(x)

is the fastest method for large enough lists, even with the implicit conversion from the input `list`

to a `numpy.array`

.

Code for generating the plot:

import numpy
import operator
import perfplot
def min_enumerate(a):
return min(enumerate(a), key=lambda x: x[1])[0]
def min_enumerate_itemgetter(a):
min_index, min_value = min(enumerate(a), key=operator.itemgetter(1))
return min_index
def getitem(a):
return min(range(len(a)), key=a.__getitem__)
def np_argmin(a):
return numpy.argmin(a)
perfplot.show(
setup=lambda n: numpy.random.rand(n).tolist(),
kernels=[
min_enumerate,
min_enumerate_itemgetter,
getitem,
np_argmin,
],
n_range=[2**k for k in range(15)],
logx=True,
logy=True,
)

## The Answer 9

*10 people think this answer is useful*

After you get the maximum values, try this:

max_val = max(list)
index_max = list.index(max_val)

Much simpler than a lot of options.

## The Answer 10

*8 people think this answer is useful*

Use a numpy array and the argmax() function

a=np.array([1,2,3])
b=np.argmax(a)
print(b) #2

## The Answer 11

*7 people think this answer is useful*

I think the answer above solves your problem but I thought I’d share a method that gives you the minimum and all the indices the minimum appears in.

minval = min(mylist)
ind = [i for i, v in enumerate(mylist) if v == minval]

This passes the list twice but is still quite fast. It is however slightly slower than finding the index of the first encounter of the minimum. So if you need just one of the minima, use Matt Anderson‘s solution, if you need them all, use this.

## The Answer 12

*6 people think this answer is useful*

Use numpy module’s function numpy.where

import numpy as n
x = n.array((3,3,4,7,4,56,65,1))

For index of minimum value:

idx = n.where(x==x.min())[0]

For index of maximum value:

idx = n.where(x==x.max())[0]

In fact, this function is much more powerful. You can pose all kinds of boolean operations
For index of value between 3 and 60:

idx = n.where((x>3)&(x<60))[0]
idx
array([2, 3, 4, 5])
x[idx]
array([ 4, 7, 4, 56])

## The Answer 13

*5 people think this answer is useful*

This is simply possible using the built-in `enumerate()`

and `max()`

function and the optional `key`

argument of the `max()`

function and a simple lambda expression:

theList = [1, 5, 10]
maxIndex, maxValue = max(enumerate(theList), key=lambda v: v[1])
# => (2, 10)

In the docs for `max()`

it says that the `key`

argument expects a function like in the `list.sort()`

function. Also see the Sorting How To.

It works the same for `min()`

. Btw it returns the first max/min value.

## The Answer 14

*5 people think this answer is useful*

Say you have a list such as:

a = [9,8,7]

The following two methods are pretty compact ways to get a tuple with the minimum element and its index. Both take a **similar** time to process. I better like the zip method, but that is my taste.

## zip method

element, index = min(list(zip(a, range(len(a)))))
min(list(zip(a, range(len(a)))))
(7, 2)
timeit min(list(zip(a, range(len(a)))))
1.36 µs ± 107 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

## enumerate method

index, element = min(list(enumerate(a)), key=lambda x:x[1])
min(list(enumerate(a)), key=lambda x:x[1])
(2, 7)
timeit min(list(enumerate(a)), key=lambda x:x[1])
1.45 µs ± 78.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

## The Answer 15

*4 people think this answer is useful*

As long as you know how to use lambda and the “key” argument, a simple solution is:

max_index = max( range( len(my_list) ), key = lambda index : my_list[ index ] )

## The Answer 16

*4 people think this answer is useful*

Simple as that :

stuff = [2, 4, 8, 15, 11]
index = stuff.index(max(stuff))

## The Answer 17

*3 people think this answer is useful*

Why bother to add indices first and then reverse them? Enumerate() function is just a special case of zip() function usage. Let’s use it in appropiate way:

my_indexed_list = zip(my_list, range(len(my_list)))
min_value, min_index = min(my_indexed_list)
max_value, max_index = max(my_indexed_list)

## The Answer 18

*3 people think this answer is useful*

Pandas has now got a much more gentle solution, try it:

`df[column].idxmax()`

## The Answer 19

*2 people think this answer is useful*

Just a minor addition to what has already been said.
`values.index(min(values))`

seems to return the smallest index of min. The following gets the largest index:

values.reverse()
(values.index(min(values)) + len(values) - 1) % len(values)
values.reverse()

The last line can be left out if the side effect of reversing in place does not matter.

To iterate through all occurrences

indices = []
i = -1
for _ in range(values.count(min(values))):
i = values[i + 1:].index(min(values)) + i + 1
indices.append(i)

For the sake of brevity. It is probably a better idea to cache `min(values), values.count(min)`

outside the loop.

## The Answer 20

*2 people think this answer is useful*

A simple way for finding the indexes with minimal value in a list if you don’t want to import additional modules:

min_value = min(values)
indexes_with_min_value = [i for i in range(0,len(values)) if values[i] == min_value]

Then choose for example the first one:

choosen = indexes_with_min_value[0]

## The Answer 21

*1 people think this answer is useful*

Dont have high enough rep to comment on existing answer.

But for https://stackoverflow.com/a/11825864/3920439 answer

This works for integers, but does not work for array of floats (at least in python 3.6)
It will raise `TypeError: list indices must be integers or slices, not float`

## The Answer 22

*0 people think this answer is useful*

https://docs.python.org/3/library/functions.html#max

If multiple items are maximal, the function returns the first one encountered. This is consistent with other sort-stability preserving tools such as `sorted(iterable, key=keyfunc, reverse=True)[0]`

To get more than just the first use the sort method.

import operator
x = [2, 5, 7, 4, 8, 2, 6, 1, 7, 1, 8, 3, 4, 9, 3, 6, 5, 0, 9, 0]
min = False
max = True
min_val_index = sorted( list(zip(x, range(len(x)))), key = operator.itemgetter(0), reverse = min )
max_val_index = sorted( list(zip(x, range(len(x)))), key = operator.itemgetter(0), reverse = max )
min_val_index[0]
>(0, 17)
max_val_index[0]
>(9, 13)
import ittertools
max_val = max_val_index[0][0]
maxes = [n for n in itertools.takewhile(lambda x: x[0] == max_val, max_val_index)]

## The Answer 23

*0 people think this answer is useful*

What about this:

a=[1,55,2,36,35,34,98,0]
max_index=dict(zip(a,range(len(a))))[max(a)]

It creates a dictionary from the items in `a`

as keys and their indexes as values, thus `dict(zip(a,range(len(a))))[max(a)]`

returns the value that corresponds to the key `max(a)`

which is the index of the maximum in a. I’m a beginner in python so I don’t know about the computational complexity of this solution.

## The Answer 24

*-1 people think this answer is useful*

Assuming you have a following list `my_list = [1,2,3,4,5,6,7,8,9,10]`

and we know that if we do `max(my_list)`

it will return `10`

and `min(my_list)`

will return `1`

. Now we want to get the index of the maximum or minimum element we can do the following.

my_list = [1,2,3,4,5,6,7,8,9,10]
max_value = max(my_list) # returns 10
max_value_index = my_list.index(max_value) # retuns 9
#to get an index of minimum value
min_value = min(my_list) # returns 1
min_value_index = my_list.index(min_value) # retuns 0