19

I have a weird list built in the following way:

[[name_d, 5], [name_e, 10], [name_a, 5]] 

I want to sort it first by the number (desc) and then, if the number is the same, by the name (asc). So the result I would like to have is:

[[name_e, 10], [name_a, 5], [name_d, 5]]

I tried to think to a lambda function that I can use in the sort method, but I'm not sure I can do it.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Giovanni Di Milia
  • 13,480
  • 13
  • 55
  • 67
  • 1
    Does this answer your question? [sort Python list with two keys but only one in reverse order](https://stackoverflow.com/questions/37693373/sort-python-list-with-two-keys-but-only-one-in-reverse-order) – user202729 Aug 14 '21 at 13:24
  • I do not understand why mine has been marked as duplicate when the other question is 5 years younger... – Giovanni Di Milia Jul 14 '23 at 16:33
  • The age has nothing to do with it. They dont want duplicates – Rohit Gupta Jul 18 '23 at 05:03

5 Answers5

40

Sort functions in python allow to pass a function as sort key:

l = [[name_d, 5], [name_e, 10], [name_a, 5]]
# copy
l_sorted = sorted(l, key=lambda x: (x[1] * -1, x[0]))
# in place
l.sort(key=lambda x: (x[1] * -1, x[0]))

Edits:
1. Sort order
2. Demonstrate copy and in place sorting

dzimiks
  • 329
  • 1
  • 3
  • 14
tback
  • 11,138
  • 7
  • 47
  • 71
2

You may sort the list twice to get the result, just reverse the order:

import operator

l = [[name_d, 5], [name_e, 10], [name_a, 5]]

l.sort(operator.itemgetter(1))
l.sort(operator.itemgetter(0), reverse=True)

Then you will get the sorted list as expected.

Maelstrom
  • 43
  • 7
0

Let's give your list a name - "arr"

arr.sort(key=lambda x:(x[0],-x[1]),reverse=True)

output - [[name_e,10],[name_d,5],[name_a,5]]

-1

    Here's something I whipped up (to solve the same type of problem). I've only checked it with my latest versions of installed Python (OS X). The import parts below are the (clunkily-named) sort keys: sortKeyWithTwoListOrders and sortKeyWith2ndThen1stListValue


#Tested under Python 2.7.1 & Python 3.2.3:

import random # Just to shuffle for demo purposes

# Our two lists to sort
firstCol=['abc','ghi','jkl','mno','bcd','hjk']
secondCol=[5,4,2,1]

# Build 2 dimensional list [[firstCol,secondCol]...]
myList = []
for firstInd in range(0, len(firstCol)):
  for secondInd in range(0, len(secondCol)):
    myList = myList + [[firstCol[firstInd],secondCol[secondInd]]]

random.shuffle(myList)

print ("myList (shuffled):")
for i in range(0,len(myList)):
  print (myList[i])

def sortKeyWithTwoListOrders(item):
  return secondCol.index(item[1]), firstCol.index(item[0])

myList.sort(key=sortKeyWithTwoListOrders)
print ("myList (sorted according to strict list order, second column then first column):")
for i in range(0,len(myList)):
  print (myList[i])

random.shuffle(myList)

print ("myList (shuffled again):")
for i in range(0,len(myList)):
  print (myList[i])

def sortKeyWith2ndThen1stListValue(item):
  return item[1], item[0]

myList.sort(key=sortKeyWith2ndThen1stListValue)
print ("myList (sorted according to *values*, second column then first column):")
for i in range(0,len(myList)):
  print (myList[i])

myList (shuffled):
['ghi', 5]
['abc', 2]
['abc', 1]
['abc', 4]
['hjk', 5]
['bcd', 4]
['jkl', 5]
['jkl', 2]
['bcd', 1]
['ghi', 1]
['mno', 5]
['ghi', 2]
['hjk', 2]
['jkl', 4]
['mno', 4]
['bcd', 2]
['bcd', 5]
['ghi', 4]
['hjk', 4]
['mno', 2]
['abc', 5]
['mno', 1]
['hjk', 1]
['jkl', 1]
myList (sorted according to strict list order, second column then first column):
['abc', 5]
['ghi', 5]
['jkl', 5]
['mno', 5]
['bcd', 5]
['hjk', 5]
['abc', 4]
['ghi', 4]
['jkl', 4]
['mno', 4]
['bcd', 4]
['hjk', 4]
['abc', 2]
['ghi', 2]
['jkl', 2]
['mno', 2]
['bcd', 2]
['hjk', 2]
['abc', 1]
['ghi', 1]
['jkl', 1]
['mno', 1]
['bcd', 1]
['hjk', 1]
myList (shuffled again):
['hjk', 4]
['ghi', 1]
['abc', 5]
['bcd', 5]
['ghi', 4]
['mno', 1]
['jkl', 1]
['abc', 1]
['hjk', 1]
['jkl', 2]
['hjk', 5]
['mno', 2]
['jkl', 4]
['ghi', 5]
['bcd', 1]
['bcd', 2]
['jkl', 5]
['abc', 2]
['hjk', 2]
['abc', 4]
['mno', 4]
['mno', 5]
['bcd', 4]
['ghi', 2]
myList (sorted according to *values*, second column then first column):
['abc', 1]
['bcd', 1]
['ghi', 1]
['hjk', 1]
['jkl', 1]
['mno', 1]
['abc', 2]
['bcd', 2]
['ghi', 2]
['hjk', 2]
['jkl', 2]
['mno', 2]
['abc', 4]
['bcd', 4]
['ghi', 4]
['hjk', 4]
['jkl', 4]
['mno', 4]
['abc', 5]
['bcd', 5]
['ghi', 5]
['hjk', 5]
['jkl', 5]
['mno', 5]
hEADcRASH
  • 1,905
  • 17
  • 17
-2

It doesn't need to be a lambda function you pass into the sort method, you can actually provide a real function since they are first-class objects in python.

L.sort(my_comparison_function)

Should work just fine

Daniel DiPaolo
  • 55,313
  • 14
  • 116
  • 115
  • 2
    -1 Comparison function goes away in Python 3, whereas the other answer is future proof. – Steven Rumbalski Oct 20 '10 at 16:12
  • I thought about this, but how can I write a comparison function that works on two different keys? basically I need a f((x[0],x[1]), (y[0],y[1])) – Giovanni Di Milia Oct 20 '10 at 16:14
  • @Steven: what are you talking about? this answer might be useless, but not for the reasons you state. [Read the docs](http://docs.python.org/py3k/library/stdtypes.html#mutable-sequence-types) – SilentGhost Oct 20 '10 at 16:14
  • 1
    @SilentGhost Maybe I'm misreading, but when I look at the linked docs i see that sort accepts a /key/ function in python 3, but not a /comparison/ function. – Steven Rumbalski Oct 20 '10 at 17:24
  • @Steven: and what is key function if not a comparison function? – SilentGhost Oct 20 '10 at 17:26
  • 1
    @SilentGhost A comparison function is called on pairs of items and "should return a negative integer if self < other, zero if self == other, a positive integer if self > other." Whereas a key function is called once for each item and returns the value(s) you want an item sorted on. See http://wiki.python.org/moin/HowTo/Sorting/ paying attention specifically to sections titled _Key_Functions_ and _The_Old_Way_Using_the_cmp_Parameter_. The key parameter was added in Python 2.4. The cmp parameter was removed in Python 3. – Steven Rumbalski Oct 20 '10 at 18:05
  • @StevenRumbalski You can pass a function as a key. Doesn't need to be a cmp function. –  Apr 17 '19 at 20:02
  • @Steve: Read the exchange. I'm talking about key functions the whole time. – Steven Rumbalski Apr 17 '19 at 22:41
  • @StevenRumbalski You are most definitely not talking about key functions the entire time. –  Apr 18 '19 at 13:56