Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort a nested list by two elements [duplicate]

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?

like image 705
Remi Crystal Avatar asked Jan 10 '16 12:01

Remi Crystal


1 Answers

>>> 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.

like image 80
Vlad Avatar answered Nov 03 '22 12:11

Vlad