Chujun Song
Chujun Song

Reputation: 158

find top k largest item of a list in original order in python

say I have the following list:

my_list = [3.5, 1.6, 2.4, 8.9, 5.6]

I want to find the top 3 largest number in its original place, so the result should be:

[3.5, 8.9, 5.6]

How could I do that? I think I can find the 3 largest number and use a filter, but I think it may not be a good idea to compare floats. Any suggestions?

Upvotes: 9

Views: 10349

Answers (5)

wim
wim

Reputation: 362647

Use a heap:

>>> import heapq
>>> heapq.nlargest(3, my_list)
[8.9, 5.6, 3.5]

Add a little polish to the same idea, to keep them in original order:

>>> from operator import itemgetter
>>> i_val = heapq.nlargest(3, enumerate(my_list), key=itemgetter(1))
>>> [val for (i, val) in sorted(i_val)]
[3.5, 8.9, 5.6]

Upvotes: 10

Chujun Song
Chujun Song

Reputation: 158

Here's my own answer, it works for the problem.

my_list = [3.5, 1.6, 2.4, 8.9, 5.6]
top_k = sorted(my_list)[-3:]
result = list(filter(lambda x : x in top_k,my_list))
print(result)

Upvotes: 1

Celius Stingher
Celius Stingher

Reputation: 18367

Here you go, you can try with this function:

my_list = [3.5, 1.6, 2.4, 5.6, 8.9]
def select_top(a,array):
    new_list = []
    extra_list = []
    for i in range(len(my_list)):
        extra_list.append(my_list[i])
    final_list = []
    for i in range(a):
        new_list.append(extra_list.index(max(extra_list)))
        extra_list.pop(extra_list.index(max(extra_list)))
    new_list = sorted(new_list,reverse=False)
    for i in new_list:
        final_list.append(array[i])
    return final_list
print(select_top(3,my_list))

I believe it is far from optimal, but you can tweak it as much as you want to get the k top numbers and have them returned in their original order. Output:

[3.5, 5.6, 8.9]

Upvotes: 1

Djaouad
Djaouad

Reputation: 22776

You can sort the index-value pairs (generated by enumerate) by the value, get the last three pairs, and then sort those by the index (and then get just the values from the index-value pairs, all this in a one-liner list comprehension):

from operator import itemgetter

my_list = [3.5, 1.6, 2.4, 5.6, 8.9]

result = [p[1] for p in sorted(sorted(enumerate(my_list), key = itemgetter(1))[-3:], key = itemgetter(0))]

print(result)

Output:

[3.5, 5.6, 8.9]

Upvotes: 3

Puddles
Puddles

Reputation: 130

How about this?

[m for m in my_list if m in sorted(my_list)[-3:]]

You're building a new list of 'm' items, from the top 3 items. The list comprehension keeps your items in order.

The order of your example is such that you could just sort it and take the 3 top items, but I think you mean that you might have the top 3 items NOT in order, like:

my_list = [3.5, 1.2, 0.3, 7.8, 3.3]

which results in

[3.5,7.8,3.3]

Upvotes: 3

Related Questions