Hashim Majeed
Hashim Majeed

Reputation: 141

How to find the 1st, 2nd, 3rd highest values in a list in Python

I know how to find the 1st highest value but don't know the rest. Keep in mind i need to print the position of the 1st 2nd and 3rd highest value.Thank You and try to keep it simple as i have only been coding for 2 months. Also they can be joint ranks

def linearSearch(Fscore_list):
    pos_list = []
    target = (max(Fscore_list))
    for i in range(len(Fscore_list)):
        if Fscore_list[i] >= target:
            pos_list.append(i)


        return pos_list

Upvotes: 14

Views: 52037

Answers (11)

Marlon Teixeira
Marlon Teixeira

Reputation: 393

In one line:

lst = [9,7,43,2,8,4]

index = [i[1] for i in sorted([(x,i) for (i,x) in enumerate(lst)])[-3:]]
print(index)
[4, 0, 2] 

Upvotes: 0

Scott Hunter
Scott Hunter

Reputation: 49803

This will create a list of the 3 largest items, and a list of the corresponding indices:

lst = [9,7,43,2,4,7,8,5,4]
values = []
values = zip(*sorted( [(x,i) for (i,x) in enumerate(f_test)], 
             reverse=True )[:3] )[0] 
posns = []
posns = zip(*sorted( [(x,i) for (i,x) in enumerate(f_test)], 
            reverse=True )[:3] )[1] 

Things are a bit more complicated if the same value can appear multiple times (this will show the highest position for a value):

lst = [9,7,43,2,4,7,8,5,4]
ranks = sorted( [(x,i) for (i,x) in enumerate(lst)], reverse=True 
)
values = []

for x,i in ranks:
    if x not in values:
        values.append( x )
        posns.append( i )
        if len(values) == 3:
            break
print zip( values, posns )

Upvotes: 7

Chandan Sharma
Chandan Sharma

Reputation: 2519

lst = [9,7,43,2,4,7,8,9,4]

temp1 = lst 
print(temp1)
    
#First Highest value: 
print(max(temp1))
temp1.remove(max(temp1))

#output: 43

# Second Highest value:
print(max(temp1))
temp1.remove(max(temp1))

#output: 9
    
        
# Third Highest Value:
print(max(temp1))

#output: 7

Upvotes: 1

Shashwat Agrawal
Shashwat Agrawal

Reputation: 125

Input : [4, 5, 1, 2, 9] 
        N = 2
Output :  [9, 5]

Input : [81, 52, 45, 10, 3, 2, 96] 
        N = 3
Output : [81, 96, 52]
# Python program to find N largest 
# element from given list of integers 
  
l = [1000,298,3579,100,200,-45,900] 
n = 4
  
l.sort() 
print(l[-n:]) 

Output:

[298, 900, 1000, 3579]

Upvotes: 2

BrianBarnett
BrianBarnett

Reputation: 11

Jupyter image of the code working This question was on my Udemy machine learning course way too soon. Scott Hunter helped me the most on this problem, but didn't get me to a pass on the site. Having to really think about the issue deeper on my own. Here is my solution, since couldn't find it anywhere else online--in terms that I understood everything that was going on*:

lst = [9,7,43,2,4,7,8,9,4]
ranks = sorted( [(x,i) for (i,x) in enumerate(lst)], reverse=True )
box = []
for x,i in ranks:
    if i&x not in box:
        box.append( x )
        if len(box) == 3:
            break
print(box)

So we have a list of numbers. To rank the numbers we sort the value with its position for every position that has a value when we enumerate/iterate the list. Then we put the highest values on top by reversing it. Now we need a box to put our information in to pull out of later, so we build that box []. Now for every value with a position put that in the box, if the value and position isn't already in the box--meaning if the value is already in the box, but the position isn't, still put in the box. And we only want three answers. Finally tell me what is in the variable called box. *Many of these answers, on this post, will most likely work.

Upvotes: 1

jwpfox
jwpfox

Reputation: 5232

Add all the values in the list to a set. This will ensure you have each value only once.

Sort the set.

Find the index of the top three values in the set in the original list.

Make sense?

Edit

thelist = [1, 45, 88, 1, 45, 88, 5, 2, 103, 103, 7, 8]
theset = frozenset(thelist)
theset = sorted(theset, reverse=True)

print('1st = ' + str(theset[0]) + ' at ' + str(thelist.index(theset[0])))
print('2nd = ' + str(theset[1]) + ' at ' + str(thelist.index(theset[1])))
print('3rd = ' + str(theset[2]) + ' at ' + str(thelist.index(theset[2])))

Edit

You still haven't told us how to handle 'joint winners' but looking at your responses to other answers I am guessing this might possibly be what you are trying to do, maybe? If this is not the output you want please give us an example of the output you are hoping to get.

thelist = [1, 45, 88, 1, 45, 88, 5, 2, 103, 103, 7, 8]
theset = frozenset(thelist)
theset = sorted(theset, reverse=True)
thedict = {}
for j in range(3):
    positions = [i for i, x in enumerate(thelist) if x == theset[j]]
    thedict[theset[j]] = positions

print('1st = ' + str(theset[0]) + ' at ' + str(thedict.get(theset[0])))
print('2nd = ' + str(theset[1]) + ' at ' + str(thedict.get(theset[1])))
print('3rd = ' + str(theset[2]) + ' at ' + str(thedict.get(theset[2])))

Output

1st = 103 at [8, 9]
2nd = 88 at [2, 5]
3rd = 45 at [1, 4]

BTW : What if all the values are the same (equal first) or for some other reason there is no third place? (or second place?). Do you need to protect against that? If you do then I'm sure you can work out appropriate safety shields to add to the code.

Upvotes: 2

robert
robert

Reputation: 34398

Use heapq.nlargest:

>>> import heapq
>>> [i
...     for x, i
...     in heapq.nlargest(
...         3,
...         ((x, i) for i, x in enumerate((0,5,8,7,2,4,3,9,1))))]
[7, 2, 3]

Upvotes: 5

beezz
beezz

Reputation: 2428

If values can appear in your list repeatedly you can try this solution.

def search(Fscore_list, num=3):
    l = Fscore_list
    res = dict([(v, []) for v in sorted(set(l), reverse=True)[:num]])
    for index, val in enumerate(l):
        if val in res:
            res[val].append(index)
    return sorted(res.items(), key=lambda x: x[0], reverse=True)

First it find num=3 highest values and create dict with empty list for indexes for it. Next it goes over the list and for every of the highest values (val in res) save it's indexes. Then just return sorted list of tuples like [(highest_1, [indexes ...]), ..]. e.g.

>>> l = [9, 7, 43, 2, 4, 7, 43, 8, 5, 8, 4]
>>> print(search(l))
[(43, [2, 6]), (9, [0]), (8, [7, 9])]

To print the positions do something like:

>>> Fscore_list = [9, 7, 43, 2, 4, 7, 43, 8, 5, 8, 4, 43, 43, 43]
>>> result = search(Fscore_list)
>>> print("1st. %d on positions %s" % (result[0][0], result[0][1]))
1st. 43 on positions [2, 6, 11, 12, 13]
>>> print("2nd. %d on positions %s" % (result[1][0], result[1][1]))
2nd. 9 on positions [0]
>>> print("3rd. %d on positions %s" % (result[2][0], result[2][1]))
3rd. 8 on positions [7, 9]

Upvotes: 0

Ravi
Ravi

Reputation: 26

To have a list filtered and returned in descending order with duplicates removed try using this function. You can pass in how many descending values you want it to return as keyword argument.

Also a side note, if the keyword argument (ordered_nums_to_return) is greater than the length of the list, it will return the whole list in descending order. if you need it to raise an exception, you can add a check to the function. If no args is passed it will return the highest value, again you can change this behaviour if you need.

list_of_nums = [2, 4, 23, 7, 4, 1]


def find_highest_values(list_to_search, ordered_nums_to_return=None):
    if ordered_nums_to_return:
        return sorted(set(list_to_search), reverse=True)[0:ordered_nums_to_return]
    return [sorted(list_to_search, reverse=True)[0]]

print find_highest_values(list_of_nums, ordered_nums_to_return=4)

Upvotes: 0

bereal
bereal

Reputation: 34281

There's a complicated O(n) algorithm, but the simplest way is to sort it, which is O(n * log n), then take the top. The trickiest part here is to sort the data while keeping the indices information.

from operator import itemgetter

def find_top_n_indices(data, top=3):
    indexed = enumerate(data)  # create pairs [(0, v1), (1, v2)...]
    sorted_data = sorted(indexed, 
                         key=itemgetter(1),   # sort pairs by value 
                         reversed=True)       # in reversed order
    return [d[0] for d in sorted_data[:top]]  # take first N indices

data = [5, 3, 6, 3, 7, 8, 2, 7, 9, 1]
print find_top_n_indices(data)  # should be [8, 5, 4]

Similarly, it can be done with heapq.nlargest(), but still you need to pack the initial data into tuples and unpack afterwards.

Upvotes: 0

Emilio M Bumachar
Emilio M Bumachar

Reputation: 2613

None is always considered smaller than any number.

>>> None<4
True
>>> None>4
False

Find the highest element, and its index. Replace it by None. Find the new highest element, and its index. This would be the second highest in the original list. Replace it by None. Find the new highest element, which is actually the third one.

Optional: restore the found elements to the list.

This is O(number of highest elements * list size), so it scales poorly if your "three" grows, but right now it's O(3n).

Upvotes: -1

Related Questions