Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python sorted two keys TWO orders [duplicate]

Here is the case, I have a list like:

[(1, a), (1, b), (5, c)]

I would like to sort the list so that it first depends on the number in descending order, then the characters in ascending order.

I tried:

sorted(theList, key = lambda x:(x[0], x[1]), reverse = True)

But the result is ordered by descending order in both the key. And apparently, reverse only take one variable I searched the web and couldn't find the solution. Please help! Thank you!

like image 616
spicyShoyo Avatar asked Aug 27 '26 11:08

spicyShoyo


2 Answers

If your first element in the tuple is an integer, you can sort by its negative value:

sorted(theList, key=lambda (num, letter): (-num, letter))
like image 66
Karin Avatar answered Aug 29 '26 00:08

Karin


According to Python documentation:

The built-in sorted() function is guaranteed to be stable. A sort is stable if it guarantees not to change the relative order of elements that compare equal — this is helpful for sorting in multiple passes (for example, sort by department, then by salary grade).

Therefore, an easy way to do it will be doing a two-pass sorting:

sorted(theList, key = lambda x:x[1])
sorted(theList, key = lambda x:x[0], reverse = True)

Or if you really want a one-liner, you can do this:

sorted(thisList, key = lambda x:x[0] * 26 - (ord(x[1]) - ord('a')), reverse = True)

This one-liner assumes that all the characters are lowercase. What it does is that it makes each two consecutive numbers have a step of 26 instead of 1, and the characters a-z are mapped to 0-25, as a finer step. Since the characters are ascending order, we subtract it from the scaled number value.

This one-liner is kind of a hack, since it wouldn't work if the x[1] has no range (i.e. also a number)

like image 44
lnyng Avatar answered Aug 29 '26 02:08

lnyng