1

I have the below code:

lst = [['candy','30'], ['apple','10'], ['baby','20'], ['baby','10']]
lst.sort(key=lambda x: (x[1], x[0]))
print(lst)

With this the output is:

[['apple', '10'], ['baby', '10'], ['baby', '20'], ['candy', '30']]

I'm trying to display the names in Descending order while the values in Ascending order. Is there a pre built way in python to achieve this?

Expected output:

[['baby', '10'], ['apple', '10'], ['baby', '20'], ['candy', '30']]
ThePyGuy
  • 17,779
  • 5
  • 18
  • 45
Pramod
  • 1,411
  • 11
  • 35
  • 66
  • 1
    What would your expected output be? Also list of lists? Or just print it that way – Andreas Jun 02 '21 at 20:10
  • 1
    What should be the output for `[['a', '1'], ['b', '2'], ['c', '3']]`? – enzo Jun 02 '21 at 20:14
  • 1
    Possible duplicate: https://stackoverflow.com/questions/4233476/sort-a-list-by-multiple-attributes – Daniel F Jun 02 '21 at 20:17
  • @DanielF No it's not. I did my search and didn't find any multi sort. Like I asked in my question, i want one in ascending and one in descending order. – Pramod Jun 02 '21 at 20:22
  • 1
    @Pramod updated my answer, now matches your expected output. – Andreas Jun 02 '21 at 20:24
  • "Like I asked in my question, i want one in ascending and one in descending order." The approach is the same (it's just a matter of making the key for the descending-order sort, compare in the opposite order, e.g. by using a numeric negative); and also the question title doesn't adequately convey that aspect of the requirements. – Karl Knechtel Sep 04 '22 at 12:23
  • But perhaps https://stackoverflow.com/questions/6666748/sort-list-of-lists-ascending-and-then-descending is a more specific duplicate. – Karl Knechtel Sep 04 '22 at 12:24

3 Answers3

3

You can achieve this by reverse sorting by name and negative value:

>>> lst = [['candy','30'], ['apple','10'], ['baby','20'], ['baby','10']]
>>> lst.sort(key=lambda x: (x[0], -int(x[1])), reverse=True)
>>> lst
[['candy', '30'], ['baby', '10'], ['baby', '20'], ['apple', '10']]

Edit: In response to OP's edit, value should take priority over name, so the correct order is:

>>> lst = [['candy','30'], ['apple','10'], ['baby','20'], ['baby','10']]
>>> lst.sort(key=lambda x: (-int(x[1]), x[0]), reverse=True)
>>> lst
[['baby', '10'], ['apple', '10'], ['baby', '20'], ['candy', '30']]
Andrew Eckart
  • 1,618
  • 9
  • 15
  • The values are not in displayed in ascending order, though. – enzo Jun 02 '21 at 20:16
  • 1
    @enzo That is another possible interpretation. I read it as "sort these (name, value) pairs by descending name and ascending value", but if they can be disassociated, then that approach is good. – Andrew Eckart Jun 02 '21 at 20:22
3

You changed the expected output, this would be the solution for that:

lst.sort(key=lambda x: (-int(x[1]), x[0]), reverse=True)
#[['baby', '10'], ['apple', '10'], ['baby', '20'], ['candy', '30']]

This was the answer before the question was edited and seperates the entries before sorting them:

print(*zip(sorted([x[0] for x in lst], reverse=True), sorted([x[1] for x in lst])))
# ('candy', '10') ('baby', '10') ('baby', '20') ('apple', '30')
Andreas
  • 8,694
  • 3
  • 14
  • 38
1

You can try setting reverse = True.

lst = [['candy','30'], ['apple','10'], ['baby','20'], ['baby','10']]
lst.sort(key=lambda x: (x[1], x[0]), reverse=True)
print(lst)
Rima
  • 1,447
  • 1
  • 6
  • 12