0

My problem's a bit more complicated than this, but essentially I have a list of scores (I'll simplify it to 6) and I need to sort them and then get rid of the lowest score. However, since this score corresponds to a person, I need the program to figure out which score came from which person (let's call them persons A, B, C, D, E, F). For example:

scores = [6,2,5,3,5,8] #this corresponds to persons A, B, C, D, E, F in order
scores.sort()

So now I will have a sorted list. I have figured out who got the lowest score but how do I know which person this corresponds to?

Alternatively, is there a way that I can brute force it by checking every value in the unsorted list to see if it's the lowest value? That would be fine also.

6 Answers6

2

simplest way: interleave (zip) lists together starting by scores and sort the tuples.

scores = [6,2,5,3,5,8]
persons =['A','B','C','D','E','F']

print(sorted(zip(scores,persons)))

note: you don't have to use a special key function for sort. So if 2 persons have a given score, the person name will act as a tiebreaker.

Result: the list contains sorted scores with corresponding persons

[(2, 'B'), (3, 'D'), (5, 'C'), (5, 'E'), (6, 'A'), (8, 'F')]

and

[x[1] for x in sorted(zip(scores,persons))]

returns the list of persons only (scores removed)

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
1

Use zip, sort by lambda, drop lowest:

pers = "ABCDEF"
scores = [6,2,5,3,5,8]

zipped = sorted(zip(pers,scores), key=lambda x: x[1]) [1:]
print(zipped)

Edit (very good point brought by Jean-François Fabre

If you do it like this (scores first) ( ==> which is Jean-François Answer )

pers = "ABCDEF"
scores = [6,2,5,3,5,8]

zipped = sorted(zip(scores,pers)) [1:]
print(zipped)

The output will be sorted by the first item in the tuple and one does not need the key or lambda - a tie on the lowest note will be resolved by the second tuple (the name) - the alphabetically lower will get kicked :/ unfair for Artner's

Output:

 [('D', 3), ('C', 5), ('E', 5), ('A', 6), ('F', 8)]
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
0

The best way is probably to construct tuples that carry the index and the value. We can do this by using enumerate(..):

from operator import itemgetter

sorted_list = sorted(enumerate(data), key=itemgetter(1))

and now sorted_list will contain tuples with as first item, the original index, and as second one the corresponding value:

>>> sorted(enumerate(scores), key=itemgetter(1))
[(1, 2), (3, 3), (2, 5), (4, 5), (0, 6), (5, 8)]

But if you for instance want to obtain the minimal element by a certain criteria, you can use min(..) and use key. For example:

worst_student = min(students, key=lambda s: s.score)

If you want to sort your students by score, we can also use this as key of sorted:

sorted_students = sort(students, key=lambda s:s.score)
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
0

You should use a dictionary in the first place, not two lists that correspond by convention.

>>> people = ['A', 'B', 'C', 'D', 'E', 'F']
>>> scores = [6,2,5,3,5,8]
>>> 
>>> p2s = dict(zip(people, scores))
>>> p2s
{'A': 6, 'C': 5, 'B': 2, 'E': 5, 'D': 3, 'F': 8}
>>> 
>>> lowest = min(p2s.values())
>>> worst = [p for p in people if p2s[p] == lowest]
>>> worst
['B']

Having a list for worst is by design, because it could happen that several people share the lowest score.

timgeb
  • 76,762
  • 20
  • 123
  • 145
0

Try using this:

for i in sorted(scores):
    index = score.index(i)
    # then do whatever you want with index
omushpapa
  • 1,663
  • 20
  • 25
0

Simple and straightforward:

places = sorted(range(len(scores)), key=lambda x: scores[x])
Green_Wizard
  • 795
  • 5
  • 11