1

I can't seem to be able to get a lambda function to sort a list of tuples by name(after being sorted by grades first). Here's the code:

def sortStudents(a):
    sorted(a, key=lambda b: (b[1],str(b[0])))
    print(a[::-1])

I'm running a doctest on it and it fails when it has to sort the students by name if they have the same grade. It just returns them without sorting them by name.

Expected:
[('Barry Thomas', 88), ('Tim Smith', 54), ('Yulia Smith', 54)]
Got:
[('Barry Thomas', 88), ('Yulia Smith', 54), ('Tim Smith', 54)]

I've found another post on here trying to do the same, and the answerer suggested the same thing i did, but it's not really working properly. Any help is greatly appreciated!

EDIT:

here are the doctests:

"""
>>> sortStudents([('Tim Jones', 54), ('Anna Smith', 56), ('Barry Thomas', 88)])
[('Barry Thomas', 88), ('Anna Smith', 56), ('Tim Jones', 54)]
>>> sortStudents([('Tim Smith', 54), ('Anna Smith', 88), ('Barry Thomas', 88)])
[('Anna Smith', 88), ('Barry Thomas', 88), ('Tim Smith', 54)]
>>> sortStudents([('Tim Smith', 54), ('Anna Smith', 54), ('Barry Thomas', 88)])
[('Barry Thomas', 88), ('Anna Smith', 54), ('Tim Smith', 54)]
>>> sortStudents([('Tim Smith', 54), ('Yulia Smith', 54), ('Barry Thomas', 88)]) 
[('Barry Thomas', 88), ('Tim Smith', 54), ('Yulia Smith', 54)]

"""
3
  • 1
    You're reversing the list at the end, so names are sorted in reverse order. Commented Nov 15, 2015 at 18:33
  • 5
    ...and your sorted result is thrown away Commented Nov 15, 2015 at 18:33
  • 3
    Oh yeah, you're actually not doing any sorting at all... all your function does is return the list reversed. Commented Nov 15, 2015 at 18:34

3 Answers 3

2

sorted() doesn't change the list, but returns a sorted list. Either re-assign the sorted list to a:

a = sorted(a, key=lambda b: (b[1],str(b[0])))

Or, better yet, sort a in-place with the list sort() method:

a.sort(key=lambda b: (b[1],str(b[0])))
Sign up to request clarification or add additional context in comments.

3 Comments

When I do either of those, it fails more doctests than before and the one i provided is still returned the same way
@Mario: Hmm try providing a SSCCE. What you gave us is not enough to solve your problem.
@Mario don't just try to plug in code and see what happens. Think about what the function is supposed to do and what it actually does. Should it modify the argument passed in? I.e. should the caller's list be modified? If not, then don't use 'a.sort()', because that will modify 'a'.
1

You're throwing the result away, and reversing inefficiently:

def sortStudents(a):
    return sorted(key=lambda b: (b[1], b[0]), reverse=True)

sorted returns an iterable that is a copy of the passed in iterable, in sorted order. It does not sort the passed list.

3 Comments

After doing this, none of the doctests pass. So I looked at what the doctest returned, it hadn't sorted by both grades and names and it didnteven reverse the list for some weird reason
@Mario You didn't post the doctests so you can't possibly expect me to conform to them. I simply went from the context I could derive.
Yeah I'm sorry for that, I didn't think it'd be necessary for my question. I updated the question with the doctests!
0

You can use the operator.itemgetter class.

>>> from operator import itemgetter
>>> arr = [('Barry Thomas', 88), ('Yulia Smith', 54), ('Tim Smith', 54)]
>>> arr.sort(key=itemgetter(1))
>>> arr
[('Barry Thomas', 88), ('Tim Smith', 54), ('Yulia Smith', 54)]

or

>>> arr = sorted(arr, key=lambda b: b[1])
# [('Barry Thomas', 88), ('Tim Smith', 54), ('Yulia Smith', 54)]

You really don't need to convert the second element in your tuple to string also sort by second element is enough.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.