Finding the 5 smallest numbers from a list in Python

11.9k views Asked by At

I have a list of names,x, and a list of scores,y, that correspond to the names.

x = {a,b,c,d,e,f,g,h,i,j,k} 
y= {8,8,15,13,12,17,18,12,14,14} 

So, a has score 8, b has scores 8, c has score 15, ..., k has score 14

I want to find the 5 smallest scores from the list,y, and get their name and have a print out similar to the following:

top5 lowest scores:

a : 8
b : 8 
e : 12
h : 12 
d : 13

Currently, I am creating a copy of the list and then using pop to keep reducing the list, but it is giving me incorrect names for the scores. However, when I create my list for the max5 values, everything comes out fine using the same method. I am unsure of a function that lets me do this in python. This is just a sample of my problem, my real problem involves store locations along with scores for those stores that I computed from a function, but I want to get the top 5 highest and 5 lowest scores. Does anyone have an efficient solution to this?

3

There are 3 answers

0
Anand S Kumar On BEST ANSWER

Python has a data structure called Dictionary that you can use to store key/value pairs . In Python , dictionary is defined as -

dict = {'a':8 , 'b':8, 'c':15, 'd':13 ...}

Then you can iterate over the key value pairs in this dictionary to find the 5 smallest numbers.

You can convert the dict to a tuple and then sort the tuple based on the second item-

import operator
dict = {'a':8 , 'b':8, 'c':15, 'd':13 ...}
sorted_dict = sorted(dict.items(), key=operator.itemgetter(1))

Instead of using a dict, you can also use a list of tuples, and use the last line in above code to sort it based on the second element of each tuple.

The list of tuples would look like -

scores = [('a',8),('b',8),('c',15),('d',13)..]
3
TaoPR On

First of all, organize your input collection

Suppose you have input x and y where each of them is the collection of labels and score, respectively:

x = ['a','b','c','d','e','f','g'] 
y = [5,3,10,2,2,1,0]

To sort x by the corresponding score y, zip them together and sort by the score, take the first 5 and thats' it:

min_list = sorted(zip(x,y), key=lambda t: t[1])[5:]

Quick explanation

It zips x and y together so you have a list of zip(x,y) = ('a',5), ('b',3), ...

Then you sort that list by the second element of each tuple sorted( zip(x,y )) where the key for sorting is the second element of tuple (t[1])

Lastly, take the first 5 elements of the sorted list [5:]

Your resultant collection looks like this:

[('g', 0), ('f', 1), ('d', 2), ('e', 2), ('b', 3)]
0
Antti Haapala -- Слава Україні On

First of all, {8,8,15...} would create a set, not a list; as sets are not ordered, you cannot pair 2 sets together like this.

Thus you'd have

x = ['a','b','c','d','e','f','g','h','i','j','k'] 
y = [8, 8, 15, 13, 12, 17, 18, 12, 14, 14]

Now, to make these into letter, score pairs, use the zip function.

pairs = zip(x, y)

And then you can find n smallest items with aptly named nsmallest function from the heapq module; you need to provide a custom key function that would provide the score for each item; we will use operator.itemgetter(1) for it (it would return the element 1 or the score for each letter, score pair:

from operator import itemgetter
from heapq import nsmallest

result = nsmallest(5, pairs, key=itemgetter(1))
print(result)

prints out

[('a', 8), ('b', 8), ('e', 12), ('h', 12), ('d', 13)]

To get the letters only, just add:

letters = [ i[0] for i in result ]