'How to find the positions of the N biggest values of a list in python?

I am trying to find the N biggest values from a list, and then print out their positions in the list.

If I would only focus on the max. value, it would look like this:

>>>>fr = [8,4,1,1,12]
>>>>print fr.index(max(fr))
4

However, my aim is to get an output like: 4,0,1 if it were for n=3. The 0 here shows the position of the second biggest value. REMEMBER, I am not interested in the value, but in their position!



Solution 1:[1]

Use heapq.nlargest with key = fr.__getitem__:

>>> import heapq
>>> fr = [8,4,1,1,12]
>>> heapq.nlargest(3, xrange(len(fr)), key=fr.__getitem__)
[4, 0, 1]

If you want the values itself, then:

>>> heapq.nlargest(3, fr)
[12, 8, 4]

Solution 2:[2]

Another way is:

[fr.index(x) for x in sorted(fr, reverse=True)[:3]]

When we compare speed of both of them...

import heapq

fr = [8, 4, 1, 1, 12]


def method_one():
    for i in xrange(10000):
        res = [fr.index(x) for x in sorted(fr, reverse=True)[:3]]


def method_two():
    for i in xrange(10000):
        heapq.nlargest(3, xrange(len(fr)), key=fr.__getitem__)


if __name__ == '__main__':
    import timeit

    print timeit.repeat(stmt='method_one()',
                    setup='from __main__ import method_one',
                    number=100)
    print timeit.repeat(stmt='method_two()',
                    setup='from __main__ import method_two',
                    number=100)

we get:

[1.1253619194030762, 1.1268768310546875, 1.128382921218872]
[2.5129621028900146, 2.529547929763794, 2.492828130722046]

Solution 3:[3]

This simplest way is to just do this

>>> fr = [8,4,1,1,12]
>>> n = 3
>>> result = [fr.index(i) for i in sorted(fr, reverse=True)][:n]
>>> print(result)
[4, 0, 1]

No libraries and dependancies.

Solution 4:[4]

The simplest possible way is -

  In[0]: import numpy as np
    ...: a = [1,4,2,5]
    ...: a.remove(sorted(a)[-1])
    ...: np.argmax(a)
 Out[0]: 1

Solution 5:[5]

select = 4    
list_val = [5.0, 0, 0, 0, 0, 5.0]
result = [list_val.index(i) for i in sorted(list_val, reverse=True)][:select]
print(result)
    
#expected: [0, 5, 1, 2]
#output: [0, 0, 1, 1]

This method won't always work.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ashwini Chaudhary
Solution 2
Solution 3 rh0dium
Solution 4 lifelonglearner_rohit
Solution 5 Sandeep Shaw