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?
Answer #1:
There are many options, for example:
import operator
index, value = max(enumerate(my_list), key=operator.itemgetter(1))
Answer #2:
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
Answer #3:
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
Answer #4:
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.
Answer #5:
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.
Answer #6:
max([(v,i) for i,v in enumerate(my_list)])
Answer #7:
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)]
Answer #8:
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])