137

I would like to sort the following list of lists by the fourth element (the integer) in each individual list.

unsorted_list = [['a','b','c','5','d'],['e','f','g','3','h'],['i','j','k','4','m']]

How can I do this? Thank you!

Andrew
  • 6,295
  • 11
  • 56
  • 95
Dana Gray
  • 1,605
  • 2
  • 13
  • 8

2 Answers2

231
unsorted_list.sort(key=lambda x: x[3])
Taymon
  • 24,950
  • 9
  • 62
  • 84
  • 83
    It's worth noting that in this method, the integers are lexicographically compared. Thus, `'5'` will be larger than `'20'`. If an integer comparison is to be made, `key=lambda x: int(x[3])` should be used – inspectorG4dget Jul 09 '13 at 18:11
  • 11
    You can also use `key=itemgetter(3)` here (from the [`operator`](http://docs.python.org/3.3/library/operator.html#operator.itemgetter) module). While some people find `itemgetter` and `attrgetter` less readable than lambdas, others use them extensively, so it's at least worth being able to read them and know what they do. – abarnert Jul 09 '13 at 18:20
  • this is the reason why I love python <3 – Thai Tran Jun 07 '15 at 09:35
  • x = [[[5,3],1.0345],[[5,6],5.098],[[5,4],4.89],[[5,1],5.97]] With a list like this is, how can we sort with respect to elements in x[0][1] ? – nidHi Dec 02 '16 at 09:47
  • 6
    To sort in descending order, add `reverse=True` as a parameter. – hb20007 Mar 16 '18 at 21:56
  • Can also do a multi-sort; `l = [[0,1,1],[0,2,1],[0,2,2]]` `l.sort(key=lambda e: e[2], reverse=True)` `l.sort(key=lambda e: e[1], reverse=True)` – Grant Langseth Apr 19 '19 at 14:46
71

Use sorted() with a key as follows -

>>> unsorted_list = [['a','b','c','5','d'],['e','f','g','3','h'],['i','j','k','4','m']]
>>> sorted(unsorted_list, key = lambda x: int(x[3]))
[['e', 'f', 'g', '3', 'h'], ['i', 'j', 'k', '4', 'm'], ['a', 'b', 'c', '5', 'd']]

The lambda returns the fourth element of each of the inner lists and the sorted function uses that to sort those list. This assumes that int(elem) will not fail for the list.

Or use itemgetter (As Ashwini's comment pointed out, this method would not work if you have string representations of the numbers, since they are bound to fail somewhere for 2+ digit numbers)

>>> from operator import itemgetter
>>> sorted(unsorted_list, key = itemgetter(3))
[['e', 'f', 'g', '3', 'h'], ['i', 'j', 'k', '4', 'm'], ['a', 'b', 'c', '5', 'd']]
LazerSharks
  • 3,089
  • 4
  • 42
  • 67
Sukrit Kalra
  • 33,167
  • 7
  • 69
  • 71
  • 1
    `itemgetter` will not work if the list contains : `[['a','b','c','100','d'],['e','f','g','2','h'],['i','j','k','4','m']]` – Ashwini Chaudhary Jul 09 '13 at 18:24
  • True. Maybe I should just remove it, the `lambda` does the trick here. – Sukrit Kalra Jul 09 '13 at 18:24
  • Yes, `itemgetter(3)` only replaces the `lambda x: x[3]`, not `lambda x: int(x[3])`. (You could `compose(int, itemgetter(3))`, but only if you're insane, or really determined to write Haskell or Lisp code in Python…) – abarnert Jul 09 '13 at 19:15
  • x = [[[5,3],1.0345],[[5,6],5.098],[[5,4],4.89],[[5,1],5.97]] With a list like this is can we sort using itemgetter() with respect to elements in x[0][1] ? – nidHi Dec 02 '16 at 09:48