9

Let's say I have a list like below:

[['Harry', '4'], ['Anthony', '10'], ['Adam', '7'], ['Joe', '6'], ['Ben', '10']]
# we can say the first element in it's lists is `name`, the second is `score`

I want sort it to:

[['Anthony', '10'], ['Ben', '10'], ['Adam', '7'], ['Joe', '6'], ['Harry', '4']]

So first sort it in descending order by the score and then sort it in ascending order by the name.


I've tried:

>>> sorted(l, key=lambda x: (int(x[1]), x[0]))
[['Harry', '4'], ['Joe', '6'], ['Adam', '7'], ['Anthony', '10'], ['Ben', '10']]

It's working, so now I just need reverse it:

>>> sorted(l, key=lambda x: (int(x[1]), x[0]), reverse=True)
[['Ben', '10'], ['Anthony', '10'], ['Adam', '7'], ['Joe', '6'], ['Harry', '4']]

Ah, reverse=True simply reversed the list but didn't give the expect output. So I just want reverse the output of int(x[1]), but not x[0].

How can I do that?

Tunaki
  • 132,869
  • 46
  • 340
  • 423
Remi Guan
  • 21,506
  • 17
  • 64
  • 87

1 Answers1

6
>>> sorted(l, key=lambda x: (-int(x[1]), x[0]))
[['Anthony', '10'], ['Ben', '10'], ['Adam', '7'], ['Joe', '6'], ['Harry', '4']]

Basically, by changing the sign of the score part of the key, the sort keys will be:

(-10, 'Anthony'),
(-10, 'Ben'),
(-7, 'Adam'),
(-6, 'Joe'),
(-4, 'Harry')

And so, with (a, b) < (c, d) <=> (a < c) or (a == c and b < d), you end up with your desired sorting order.

Vlad
  • 18,195
  • 4
  • 41
  • 71