Pythonic way to find maximum value and its index in a list?

Question:

If I want the maximum value in a list, I can just write max(List), but what if I also need the index of the maximum value?

I can write something like this:

maximum=0
for i,value in enumerate(List):
    if value>maximum:
        maximum=value
        index=i

But it looks tedious to me.

And if I write:

List.index(max(List))

Then it will iterate the list twice.

Is there a better way?

Asked By: Sunny88

||

Answers:

There are many options, for example:

import operator
index, value = max(enumerate(my_list), key=operator.itemgetter(1))
Answered By: Sven Marnach

I think the accepted answer is great, but why don’t you do it explicitly? I feel more people would understand your code, and that is in agreement with PEP 8:

max_value = max(my_list)
max_index = my_list.index(max_value)

This method is also about three times faster than the accepted answer:

import random
from datetime import datetime
import operator

def explicit(l):
    max_val = max(l)
    max_idx = l.index(max_val)
    return max_idx, max_val

def implicit(l):
    max_idx, max_val = max(enumerate(l), key=operator.itemgetter(1))
    return max_idx, max_val

if __name__ == "__main__":
    from timeit import Timer
    t = Timer("explicit(l)", "from __main__ import explicit, implicit; "
          "import random; import operator;"
          "l = [random.random() for _ in xrange(100)]")
    print "Explicit: %.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)

    t = Timer("implicit(l)", "from __main__ import explicit, implicit; "
          "import random; import operator;"
          "l = [random.random() for _ in xrange(100)]")
    print "Implicit: %.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)

Results as they run in my computer:

Explicit: 8.07 usec/pass
Implicit: 22.86 usec/pass

Other set:

Explicit: 6.80 usec/pass
Implicit: 19.01 usec/pass
Answered By: Escualo

This answer is 33 times faster than @Escualo assuming that the list is very large, and assuming that it’s already an np.array(). I had to turn down the number of test runs because the test is looking at 10000000 elements not just 100.

import random
from datetime import datetime
import operator
import numpy as np

def explicit(l):
    max_val = max(l)
    max_idx = l.index(max_val)
    return max_idx, max_val

def implicit(l):
    max_idx, max_val = max(enumerate(l), key=operator.itemgetter(1))
    return max_idx, max_val

def npmax(l):
    max_idx = np.argmax(l)
    max_val = l[max_idx]
    return (max_idx, max_val)

if __name__ == "__main__":
    from timeit import Timer

t = Timer("npmax(l)", "from __main__ import explicit, implicit, npmax; "
      "import random; import operator; import numpy as np;"
      "l = np.array([random.random() for _ in xrange(10000000)])")
print "Npmax: %.2f msec/pass" % (1000  * t.timeit(number=10)/10 )

t = Timer("explicit(l)", "from __main__ import explicit, implicit; "
      "import random; import operator;"
      "l = [random.random() for _ in xrange(10000000)]")
print "Explicit: %.2f msec/pass" % (1000  * t.timeit(number=10)/10 )

t = Timer("implicit(l)", "from __main__ import explicit, implicit; "
      "import random; import operator;"
      "l = [random.random() for _ in xrange(10000000)]")
print "Implicit: %.2f msec/pass" % (1000  * t.timeit(number=10)/10 )

Results on my computer:

Npmax: 8.78 msec/pass
Explicit: 290.01 msec/pass
Implicit: 790.27 msec/pass
Answered By: benathon

With Python’s built-in library, it’s pretty easy:

a = [2, 9, -10, 5, 18, 9] 
max(xrange(len(a)), key = lambda x: a[x])

This tells max to find the largest number in the list [0, 1, 2, ..., len(a)], using the custom function lambda x: a[x], which says that 0 is actually 2, 1 is actually 9, etc.

Answered By: Sunil Kapil
max([(v,i) for i,v in enumerate(my_list)])
Answered By: Luis Sobrecueva
max([(value,index) for index,value in enumerate(your_list)]) #if maximum value is present more than once in your list then this will return index of the last occurrence

If maximum value in present more than once and you want to get all indices,

max_value = max(your_list)
maxIndexList = [index for index,value in enumerate(your_list) if value==max(your_list)]
Answered By: Taohidul Islam

Maybe you need a sorted list anyway?

Try this:

your_list = [13, 352, 2553, 0.5, 89, 0.4]
sorted_list = sorted(your_list)
index_of_higher_value = your_list.index(sorted_list[-1])
Answered By: Mattias

Here is a complete solution to your question using Python’s built-in functions:

# Create the List
numbers = input("Enter the elements of the list. Separate each value with a comma. Do not put a comma at the end.n").split(",") 

# Convert the elements in the list (treated as strings) to integers
numberL = [int(element) for element in numbers] 

# Loop through the list with a for-loop

for elements in numberL:
    maxEle = max(numberL)
    indexMax = numberL.index(maxEle)

print(maxEle)
print(indexMax)
Answered By: Samdom For Peace

I would suggest a very simple way:

import numpy as np
l = [10, 22, 8, 8, 11]
print(np.argmax(l))
print(np.argmin(l))

Hope it helps.

Answered By: Igor Manzhos

I made some big lists. One is a list and one is a numpy array.

import numpy as np
import random
arrayv=np.random.randint(0,10,(100000000,1))
listv=[]
for i in range(0,100000000):
    listv.append(random.randint(0,9))

Using jupyter notebook’s %%time function I can compare the speed of various things.

2 seconds:

%%time
listv.index(max(listv))

54.6 seconds:

%%time
listv.index(max(arrayv))

6.71 seconds:

%%time
np.argmax(listv)

103 ms:

%%time
np.argmax(arrayv)

numpy’s arrays are crazy fast.

Answered By: AndrewGraham

List comprehension method:

Let’s say you have some list List = [5,2,3,8]

Then [i for i in range(len(List)) if List[i] == max(List)] would be a pythonic list comprehension method to find the values "i" where List[i] == max(List).

It is easily scalable for arrays that are lists of lists, simply by doing a for loop.

For instance, with an arbitrary list of lists "array" and initalizing "index" as an empty list.

array = [[5, 0, 1, 1], 
[1, 0, 1, 5], 
[0, 1, 6, 0], 
[0, 4, 3, 0], 
[5, 2, 0, 0], 
[5, 0, 1, 1], 
[0, 6, 0, 1], 
[0, 1, 0, 6]]
index = []

for List in array:
    index.append([i for i in range(len(List)) if List[i] == max(List)])
index

Output: [[0], [3], [2], [1], [0], [0], [1], [3]]

Answered By: Eliot Behr
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.