Find minimum value index in list python

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

answered Aug 6, 2012 at 9:43

5

if is_min_level:
    return values.index[min[values]]
else:
    return values.index[max[values]]

answered Mar 18, 2010 at 23:23

too much phptoo much php

86.4k34 gold badges127 silver badges135 bronze badges

7

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].

jamylak

124k29 gold badges227 silver badges227 bronze badges

answered Mar 19, 2010 at 0:18

Matt AndersonMatt Anderson

18.7k11 gold badges39 silver badges55 bronze badges

2

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]

answered Nov 23, 2012 at 17:41

dr.hazdr.haz

1,3971 gold badge9 silver badges5 bronze badges

1

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]

answered Dec 21, 2012 at 11:53

Ant6nAnt6n

1,7681 gold badge17 silver badges25 bronze badges

0

seq=[1.1412, 4.3453, 5.8709, 0.1314]
seq.index[min[seq]]

Will give you first index of minimum.

Asclepius

52.2k15 gold badges151 silver badges131 bronze badges

answered Sep 7, 2013 at 21:30

AndyAndy

4814 silver badges3 bronze badges

0

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]

answered Jan 5, 2019 at 6:24

0

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

It turns out that

min[range[len[a]], key=a.__getitem__]

is the fastest method for small and large lists.

[In former versions, np.argmin used to take the cake.]

Code for generating the plot:

import numpy as np
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 np.argmin[a]


b = perfplot.bench[
    setup=lambda n: np.random.rand[n].tolist[],
    kernels=[
        min_enumerate,
        min_enumerate_itemgetter,
        getitem,
        np_argmin,
    ],
    n_range=[2**k for k in range[15]],
]
b.show[]

answered May 23, 2017 at 7:58

Nico SchlömerNico Schlömer

48.7k24 gold badges186 silver badges223 bronze badges

3

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.

answered Apr 14, 2011 at 18:22

4

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.

answered Jan 11, 2018 at 16:57

alpha_989alpha_989

4,5511 gold badge34 silver badges47 bronze badges

Use a numpy array and the argmax[] function

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

answered Jan 29, 2018 at 18:07

0

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

df[column].idxmax[]

answered Aug 10, 2020 at 9:44

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.

answered Oct 28, 2016 at 9:35

Simon HänischSimon Hänisch

4,4052 gold badges29 silver badges40 bronze badges

2

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

Chủ Đề