[python] How to find all positions of the maximum value in a list?

I have a list:

a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50,
             35, 41, 49, 37, 19, 40, 41, 31]

max element is 55 (two elements on position 9 and 12)

I need to find on which position(s) the maximum value is situated. Please, help.

This question is related to python list max

The answer is


Similar idea with a list comprehension but without enumerate

m = max(a)
[i for i in range(len(a)) if a[i] == m]

I came up with the following and it works as you can see with max, min and others functions over lists like these:

So, please consider the next example list find out the position of the maximum in the list a:

>>> a = [3,2,1, 4,5]

Using the generator enumerate and making a casting

>>> list(enumerate(a))
[(0, 3), (1, 2), (2, 1), (3, 4), (4, 5)]

At this point, we can extract the position of max with

>>> max(enumerate(a), key=(lambda x: x[1]))
(4, 5)

The above tells us, the maximum is in the position 4 and his value is 5.

As you see, in the key argument, you can find the maximum over any iterable object by defining a lambda appropriate.

I hope that it contributes.

PD: As @PaulOyster noted in a comment. With Python 3.x the min and max allow a new keyword default that avoid the raise exception ValueError when argument is empty list. max(enumerate(list), key=(lambda x:x[1]), default = -1)


Just one line:

idx = max(range(len(a)), key = lambda i: a[i])

a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 
         55, 23, 31, 55, 21, 40, 18, 50,
         35, 41, 49, 37, 19, 40, 41, 31]

import pandas as pd

pd.Series(a).idxmax()

9

That is how I usually do it.


If you want to get the indices of the largest n numbers in a list called data, you can use Pandas sort_values:

pd.Series(data).sort_values(ascending=False).index[0:n]

Also a solution, which gives only the first appearance, can be achieved by using numpy:

>>> import numpy as np
>>> a_np = np.array(a)
>>> np.argmax(a_np)
9

import operator

def max_positions(iterable, key=None, reverse=False):
  if key is None:
    def key(x):
      return x
  if reverse:
    better = operator.lt
  else:
    better = operator.gt

  it = enumerate(iterable)
  for pos, item in it:
    break
  else:
    raise ValueError("max_positions: empty iterable")
    # note this is the same exception type raised by max([])
  cur_max = key(item)
  cur_pos = [pos]

  for pos, item in it:
    k = key(item)
    if better(k, cur_max):
      cur_max = k
      cur_pos = [pos]
    elif k == cur_max:
      cur_pos.append(pos)

  return cur_max, cur_pos

def min_positions(iterable, key=None, reverse=False):
  return max_positions(iterable, key, not reverse)

>>> L = range(10) * 2
>>> L
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> max_positions(L)
(9, [9, 19])
>>> min_positions(L)
(0, [0, 10])
>>> max_positions(L, key=lambda x: x // 2, reverse=True)
(0, [0, 1, 10, 11])

>>> max(enumerate([1,2,3,32,1,5,7,9]),key=lambda x: x[1])
>>> (3, 32)

I can't reproduce the @SilentGhost-beating performance quoted by @martineau. Here's my effort with comparisons:

=== maxelements.py ===

a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50,
             35, 41, 49, 37, 19, 40, 41, 31]
b = range(10000)
c = range(10000 - 1, -1, -1)
d = b + c

def maxelements_s(seq): # @SilentGhost
    ''' Return list of position(s) of largest element '''
    m = max(seq)
    return [i for i, j in enumerate(seq) if j == m]

def maxelements_m(seq): # @martineau
    ''' Return list of position(s) of largest element '''
    max_indices = []
    if len(seq):
        max_val = seq[0]
        for i, val in ((i, val) for i, val in enumerate(seq) if val >= max_val):
            if val == max_val:
                max_indices.append(i)
            else:
                max_val = val
                max_indices = [i]
    return max_indices

def maxelements_j(seq): # @John Machin
    ''' Return list of position(s) of largest element '''
    if not seq: return []
    max_val = seq[0] if seq[0] >= seq[-1] else seq[-1]
    max_indices = []
    for i, val in enumerate(seq):
        if val < max_val: continue
        if val == max_val:
            max_indices.append(i)
        else:
            max_val = val
            max_indices = [i]
    return max_indices

Results from a beat-up old laptop running Python 2.7 on Windows XP SP3:

>\python27\python -mtimeit -s"import maxelements as me" "me.maxelements_s(me.a)"
100000 loops, best of 3: 6.88 usec per loop

>\python27\python -mtimeit -s"import maxelements as me" "me.maxelements_m(me.a)"
100000 loops, best of 3: 11.1 usec per loop

>\python27\python -mtimeit -s"import maxelements as me" "me.maxelements_j(me.a)"
100000 loops, best of 3: 8.51 usec per loop

>\python27\python -mtimeit -s"import maxelements as me;a100=me.a*100" "me.maxelements_s(a100)"
1000 loops, best of 3: 535 usec per loop

>\python27\python -mtimeit -s"import maxelements as me;a100=me.a*100" "me.maxelements_m(a100)"
1000 loops, best of 3: 558 usec per loop

>\python27\python -mtimeit -s"import maxelements as me;a100=me.a*100" "me.maxelements_j(a100)"
1000 loops, best of 3: 489 usec per loop

Here is the max value and the indexes it appears at:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50, 35, 41, 49, 37, 19, 40, 41, 31]
>>> for i, x in enumerate(a):
...     d[x].append(i)
... 
>>> k = max(d.keys())
>>> print k, d[k]
55 [9, 12]

Later: for the satisfaction of @SilentGhost

>>> from itertools import takewhile
>>> import heapq
>>> 
>>> def popper(heap):
...     while heap:
...         yield heapq.heappop(heap)
... 
>>> a = [32, 37, 28, 30, 37, 25, 27, 24, 35, 55, 23, 31, 55, 21, 40, 18, 50, 35, 41, 49, 37, 19, 40, 41, 31]
>>> h = [(-x, i) for i, x in enumerate(a)]
>>> heapq.heapify(h)
>>> 
>>> largest = heapq.heappop(h)
>>> indexes = [largest[1]] + [x[1] for x in takewhile(lambda large: large[0] == largest[0], popper(h))]
>>> print -largest[0], indexes
55 [9, 12]

The chosen answer (and most others) require at least two passes through the list.
Here's a one pass solution which might be a better choice for longer lists.

Edited: To address the two deficiencies pointed out by @John Machin. For (2) I attempted to optimize the tests based on guesstimated probability of occurrence of each condition and inferences allowed from predecessors. It was a little tricky figuring out the proper initialization values for max_val and max_indices which worked for all possible cases, especially if the max happened to be the first value in the list — but I believe it now does.

def maxelements(seq):
    ''' Return list of position(s) of largest element '''
    max_indices = []
    if seq:
        max_val = seq[0]
        for i,val in ((i,val) for i,val in enumerate(seq) if val >= max_val):
            if val == max_val:
                max_indices.append(i)
            else:
                max_val = val
                max_indices = [i]

    return max_indices

You can do it in various ways.

The old conventional way is,

maxIndexList = list() #this list will store indices of maximum values
maximumValue = max(a) #get maximum value of the list
length = len(a)       #calculate length of the array

for i in range(length): #loop through 0 to length-1 (because, 0 based indexing)
    if a[i]==maximumValue: #if any value of list a is equal to maximum value then store its index to maxIndexList
        maxIndexList.append(i)

print(maxIndexList) #finally print the list

Another way without calculating the length of the list and storing maximum value to any variable,

maxIndexList = list()
index = 0 #variable to store index
for i in a: #iterate through the list (actually iterating through the value of list, not index )
    if i==max(a): #max(a) returns a maximum value of list.
        maxIndexList.append(index) #store the index of maximum value
index = index+1 #increment the index

print(maxIndexList)

We can do it in Pythonic and smart way! Using list comprehension just in one line,

maxIndexList = [i for i,j in enumerate(a) if j==max(a)] #here,i=index and j = value of that index

All my codes are in Python 3.


This code is not as sophisticated as the answers posted earlier but it will work:

m = max(a)
n = 0    # frequency of max (a)
for number in a :
    if number == m :
        n = n + 1
ilist = [None] * n  # a list containing index values of maximum number in list a.
ilistindex = 0
aindex = 0  # required index value.    
for number in a :
    if number == m :
        ilist[ilistindex] = aindex
        ilistindex = ilistindex + 1
    aindex = aindex + 1

print ilist

ilist in the above code would contain all the positions of the maximum number in the list.


You can also use the numpy package:

import numpy as np
A = np.array(a)
maximum_indices = np.where(A==max(a))

This will return an numpy array of all the indices that contain the max value

if you want to turn this to a list:

maximum_indices_list = maximum_indices.tolist()

@shash answered this elsewhere

A Pythonic way to find the index of the maximum list element would be

position = max(enumerate(a), key=lambda x: x[1])[0]

Which does one pass. Yet, it is slower than the solution by @Silent_Ghost and, even more so, @nmichaels:

for i in s m j n; do echo $i;  python -mtimeit -s"import maxelements as me" "me.maxelements_${i}(me.a)"; done
s
100000 loops, best of 3: 3.13 usec per loop
m
100000 loops, best of 3: 4.99 usec per loop
j
100000 loops, best of 3: 3.71 usec per loop
n
1000000 loops, best of 3: 1.31 usec per loop

a.index(max(a))

will tell you the index of the first instance of the largest valued element of list a.


Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to list

Convert List to Pandas Dataframe Column Python find elements in one list that are not in the other Sorting a list with stream.sorted() in Java Python Loop: List Index Out of Range How to combine two lists in R How do I multiply each element in a list by a number? Save a list to a .txt file The most efficient way to remove first N elements in a list? TypeError: list indices must be integers or slices, not str Parse JSON String into List<string>

Examples related to max

Min and max value of input in angular4 application numpy max vs amax vs maximum mongodb how to get max value from collections Python find min max and average of a list (array) Max length UITextField How to find the highest value of a column in a data frame in R? MAX function in where clause mysql Check if all values in list are greater than a certain number How do I get the max and min values from a set of numbers entered? SQL: Group by minimum value in one field while selecting distinct rows