53

Is there a way to use the sort() method or any other method to sort a list by column? Lets say I have the list:

[
[John,2],
[Jim,9],
[Jason,1]
]

And I wanted to sort it so that it would look like this:

[
[Jason,1],
[John,2],
[Jim,9],
]

What would be the best approach to do this?

Edit:

Right now I am running into an index out of range error. I have a 2 dimensional array that is lets say 1000 rows b 3 columns. I want to sort it based on the third column. Is this the right code for that?

sorted_list = sorted(list_not_sorted, key=lambda x:x[2])
Web Hopeful
  • 741
  • 2
  • 6
  • 11
  • see: http://stackoverflow.com/questions/2828059/sorting-arrays-in-numpy-by-column – duhaime Nov 25 '13 at 00:40
  • Right now I am running into an index out of range error. I have a 2 dimensional array that is lets say 1000 rows b 3 columns. I want to sort it based on the third column. Is this the right code for that? sorted_list = sorted(list_not_sorted, key=lambda x:x[2]) – Web Hopeful Nov 25 '13 at 01:11
  • In response to your edit, since lists are zero indexed, yes x[2] is the third column. The moral of the story is, you can use a key and lambda or an actual function to sort by some stipulation in the `sorted` and `sort` functions. – squiguy Nov 25 '13 at 02:51

6 Answers6

79

Yes. The sorted built-in accepts a key argument:

sorted(li,key=lambda x: x[1])
Out[31]: [['Jason', 1], ['John', 2], ['Jim', 9]]

note that sorted returns a new list. If you want to sort in-place, use the .sort method of your list (which also, conveniently, accepts a key argument).

or alternatively,

from operator import itemgetter
sorted(li,key=itemgetter(1))
Out[33]: [['Jason', 1], ['John', 2], ['Jim', 9]]

Read more on the python wiki.

roippi
  • 25,533
  • 4
  • 48
  • 73
  • Might want to mention that this will return a new list. –  Nov 25 '13 at 01:02
  • 2
    Indeed. If you want to modify the original list, that would be `li.sort(key=whatever)`. – user2357112 Nov 25 '13 at 01:03
  • And how can I get the natural sorting? As in here sorted sorts based on the digit place and '411' will be sorted first then '67'. – Abhishek Jain May 27 '19 at 10:34
  • 1
    @AbhishekJain The type of your data is string, which is why "411" is coming before "67". [Convert to number](https://stackoverflow.com/questions/379906/how-do-i-parse-a-string-to-a-float-or-int) – bobobobo Feb 13 '21 at 23:32
14

You can use the sorted method with a key.

sorted(a, key=lambda x : x[1])
squiguy
  • 32,370
  • 6
  • 56
  • 63
12

You can use list.sort with its optional key parameter and a lambda expression:

>>> lst = [
...     ['John',2],
...     ['Jim',9],
...     ['Jason',1]
... ]
>>> lst.sort(key=lambda x:x[1])
>>> lst
[['Jason', 1], ['John', 2], ['Jim', 9]]
>>>

This will sort the list in-place.


Note that for large lists, it will be faster to use operator.itemgetter instead of a lambda:

>>> from operator import itemgetter
>>> lst = [
...     ['John',2],
...     ['Jim',9],
...     ['Jason',1]
... ]
>>> lst.sort(key=itemgetter(1))
>>> lst
[['Jason', 1], ['John', 2], ['Jim', 9]]
>>>
  • What exactly is the "lambda" key? – Web Hopeful Nov 25 '13 at 00:51
  • 1
    @user3024130 - The `lambda` creates an inline function for the `key` parameter. I added a link to explain better. Using a `lambda` would be no different than doing `def func(x): return x[1]` and then `lst.sort(key=func)`. –  Nov 25 '13 at 00:54
  • Okay that makes sense. How would you sort it from highest to lowest instead of lowest to highest? – Web Hopeful Nov 25 '13 at 01:35
  • 3
    @user3024130 - Simple. Use this: `lst.sort(key=lambda x:x[1], reverse=True)`. `list.sort` also takes an optional `reverse` parameter. If it is set to `True`, the list is sorted highest to lowest. Otherwise, it is lowest to highest. –  Nov 25 '13 at 01:43
3
sorted(list, key=lambda x: x[1])

Note: this works on time variable too.

kevin
  • 1,107
  • 1
  • 13
  • 17
1

The optional key parameter to sort/sorted is a function. The function is called for each item and the return values determine the ordering of the sort

>>> lst = [['John', 2], ['Jim', 9], ['Jason', 1]]
>>> def my_key_func(item):
...     print("The key for {} is {}".format(item, item[1]))
...     return item[1]
... 
>>> sorted(lst, key=my_key_func)
The key for ['John', 2] is 2
The key for ['Jim', 9] is 9
The key for ['Jason', 1] is 1
[['Jason', 1], ['John', 2], ['Jim', 9]]

taking the print out of the function leaves

>>> def my_key_func(item):
...     return item[1]

This function is simple enough to write "inline" as a lambda function

>>> sorted(lst, key=lambda item: item[1])
[['Jason', 1], ['John', 2], ['Jim', 9]]
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
0

below solution worked for me in case of required number is float. Solution:

table=sorted(table,key=lambda x: float(x[5]))
for row in table[:]:
    Ntable.add_row(row)

'