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

5

9

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?

Samal answered 23/9, 2019 at 21:6 Comment(0)
E
10

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]
Ethelda answered 23/9, 2019 at 21:26 Comment(2)
Minor quibble: There is no explicit use of a heap here. The heapq module provides a number of utility functions that may or may not be implemented with heaps; the current implementation of nlargest usually uses a heap under the hood, but not always (as it happens, it probably shouldn't use heaps as often as it does, as sorted is typically more efficient if most of the results would be kept). Up-voted regardless; this is what nlargest exists for, and this has some of the cleanest examples of decorating and undecorating.Cripps
FWIW in OP case, it does heapify.Ethelda
T
3

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]
Tohubohu answered 23/9, 2019 at 21:23 Comment(0)
U
3

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]
Upbraid answered 23/9, 2019 at 21:25 Comment(0)
G
1

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]
Gammer answered 23/9, 2019 at 21:19 Comment(2)
I think the result is correct, but I would prefer to write shorter code. Still, thanks very much!!!Samal
Sure, here you have a defined function that'll make you never have to right the code again, regardless of the k you choose or length of the array! If the answer is helpful make sure to upvote it and accept the answer that is the best for you!Gammer
S
1

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)
Samal answered 24/9, 2019 at 0:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.