12

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!

3
  • 1
    Where is 0 in input? Commented May 5, 2014 at 13:28
  • 0 shows the position of the second biggest values... REMEMBER, I am not interested in the value, but in their PoSiTiOn! :-) Thanks! Commented May 5, 2014 at 13:33
  • 1
    @thefourtheye 0 is the position of the 2nd largest number in the list. Commented May 5, 2014 at 13:33

5 Answers 5

24

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]
Sign up to request clarification or add additional context in comments.

2 Comments

nice! That is exactly what I needed! You mind though explaining how it works? Thanks!
@user3604362 It sorts the indices xrange(len(fr)) based on the key i.e the value at those indices in fr, and return the 3 largest value. It is not exactly sorting but using heapq algorithm to get the largest items.
9

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]

3 Comments

of course you're not going to see the O(n log(n)) behaviour of sort with just 5 items. sheesh
I don't think it stops at the largest 3 numbers, instead it lists all indices. [fr.index(x) for x in sorted(fr, reverse=True)][:3], whereas this will get the first 3 elements.
Note that this does not work where the list may contain duplicate elements. Take fr = [8,8,1,2,12] and n = 4, then result=[4, 0, 0, 3] which may not be what the OP asked for. The heap solution gives the correct [4,0,1,3] indices though
4

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.

Comments

1

it's always easy to convert the list to numpy array and deal with it.

import numpy as np

arr = np.array([10, 5, 8, 15, 15, 12])

sorted_indices = np.argsort(arr)[::-1]
largest_indices = sorted_indices[:3]
print(largest_indices)

Output: [4 3 5]

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.