0

I want to sort grades alphabetically in a function that are in tuples, such as:

sortGrades([('John Smith', 'C'), ('Adam Thomas', 'B'), ('Katie Johnson', 'A')])

and also, numerically, like this:

sortGrades([('John Smith', 54), ('Adam Smith', 54), ('Thomas King', 88)]) 

So it will sort the tuples by highest score and highest grade. The names should also be sorted alphabetically if there are two people with the same score.

So far my function looks like this:

def sortGrades(list):
return sorted(list, key=lambda x:(-x[1],x[0]))

However this does not seem to work when I sort grades (A, B, C), it returns a "TypeError: bad operand type for unary -: 'str'"

Any idea how to make it work for strings and integers at the same time?

  • edited question, need it to work for both strings and ints!
4
  • "how to make it work for strings" or "how to make it work for both strings and integers"? Commented Nov 20, 2014 at 19:49
  • Both strings and integers. My bad, sorry! I just need the one function to do it all. Commented Nov 20, 2014 at 19:49
  • Must sortGrades() operate without any indication as to which type of list to expect? Commented Nov 20, 2014 at 19:51
  • If possible, yes. I don't know how to make it work for both at once, I'd rather not have two separate functions Commented Nov 20, 2014 at 19:53

4 Answers 4

1

In a similar way to what you wrote, I would do it like this:

return sorted(list, key=lambda x:(tuple(-ord(c) for c in x[1]), x[0]))

This basically negates all the characters in the string, so you can still sort in lexographic order.

Of course, since your case only has single-character strings, calling ord once would work.

If you want for this to work with both strings and ints, then it's a bad idea. How do you compare 'A' and 54? It's better to have two versions of the function.

Sign up to request clarification or add additional context in comments.

Comments

0

If all your grades are single uppercase letters, you could use key=lambda x: (-ord(x[1]), x[0])) (sorting by the ASCII values of the characters).

Comments

0

Try this, it's satisfactory for comparing a list that contains alpha grades OR a list that contains numerical grades.

def sortedGrades(some_contents):
   def as_numeric(x): return (-x[1],x[0])
   def as_alpha(x): return (-ord(x[1]), x[0])

   sort_keys = { type(0): as_numeric,
     type('A'): as_alpha,
   }
   if not some_contents:
      return some_contents
   sort_key = sort_keys[type(some_contents[0][1])]
   return sorted(some_contents, key=sort_key)

Comments

0

One option is to make a dict that translates notes to ints and pick values from that dict:

a = [('John Smith', 'B'), ('Adam Thomas', 'A'), ('Katie Johnson', 'C')]
b = [('John Smith', 54), ('Adam Smith', 54), ('Thomas King', 88)]

def sort_grades(lst):
    notes = {'C':1, 'B':2, 'A':3}
    return sorted(lst, key=lambda (x, y): (notes.get(y, y), x))

print sort_grades(a)
print sort_grades(b)

get(y, y) basically means "if dicy[y] exists, return that, otherwise return y itself".

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.