39

I have following type of list

lst = [ [1, 0.23], [2, 0.39], [4, 0.31], [5, 0.27], ]

I want to sort this in descending order of the second column. I tried built-in sorted() function in python, but it gives me 'TypeError' : 'float' object is unsubscriptable.

CC BY-SA 4.0
4
  • 3
    I'm sorry, but that's not a list. That is a sequence of numbers with newlines, but not any Python structure. Please post the actual code that failed for you, and the representation of the list. Commented Sep 1, 2013 at 22:46
  • 2
    Now we have a sequence of python lists; is there an outer list? Commented Sep 1, 2013 at 22:47
  • 13
    Clearly not off-topic, since it's the #1 Google search result for sorting a 2D list in Python, and the best answer has 15 up-votes. Commented Jun 26, 2017 at 15:53
  • 1
    Agreed. If StackOverflow explains why this is off-topic, we could improve it. It is a typical question to ask how to do a non-trivial task in Python, and the task has multiple approaches as shown below. Commented Sep 7, 2020 at 16:30

2 Answers 2

71

You can use a lambda:

>>> li=[[1, 0.23], ... [2, 0.39], ... [4, 0.31], ... [5, 0.27]] >>> sorted(li,key=lambda l:l[1], reverse=True) [[2, 0.39], [4, 0.31], [5, 0.27], [1, 0.23]]

Or the other way:

>>> sorted(li,key=lambda l:l[1]) [[1, 0.23], [5, 0.27], [4, 0.31], [2, 0.39]]
CC BY-SA 3.0
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the answer, works a treat, but mind explaining what 'l:l[1]' do?
A lambda is a small anonymous function in Python. The l is the argument to the lambda separated by the body of the function by :. The l[1] takes the list passed to the lambda and returns the second item (subscript [1] is the second item...)
23

To sort a list of lists on the second column, use operator.itemgetter() for ease and clarity:

from operator import itemgetter outputlist = sorted(inputlist, key=itemgetter(1), reverse=True)

or, to sort in-place:

from operator import itemgetter inputlist.sort(key=itemgetter(1), reverse=True)

itemgetter() is a little faster than using a lambda for the task.

Demo:

>>> from operator import itemgetter >>> inputlist = [ ... [1, 0.23], ... [2, 0.39], ... [4, 0.31], ... [5, 0.27], ... ] >>> sorted(inputlist, key=itemgetter(1), reverse=True) [[2, 0.39], [4, 0.31], [5, 0.27], [1, 0.23]]

You'd only see your exception if you had floating point values in your inputlist directly:

>>> inputlist.append(4.2) >>> inputlist [[1, 0.23], [2, 0.39], [4, 0.31], [5, 0.27], 4.2] >>> sorted(inputlist, key=itemgetter(1), reverse=True) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'float' object is not subscriptable

(for Python 3; Python 2's error message is slightly different, resulting in TypeError: 'float' object has no attribute '__getitem__' instead).

This is because the itergetter(1) call is applied to all elements in the outer list but only works on nested ordered sequences, not on the one floating point value now added.

CC BY-SA 3.0

2 Comments

I tried this, but since my second column is float it gives me 'TypeError' : 'float' object is unsubscriptable
@ChinthakaNadunRatnaweera: No, then your list is not nested. You have float values directly referenced in your outer list. Print your list and copy it to your question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.