How to sort a list/tuple of lists/tuples by the element at a given index?

838,047

Solution 1

sorted_by_second = sorted(data, key=lambda tup: tup[1])

or:

data.sort(key=lambda tup: tup[1])  # sorts in place

The default sort mode is ascending. To sort in descending order use the option reverse=True:

sorted_by_second = sorted(data, key=lambda tup: tup[1], reverse=True)

or:

data.sort(key=lambda tup: tup[1], reverse=True)  # sorts in place

Solution 2

from operator import itemgetter
data.sort(key=itemgetter(1))

Solution 3

For sorting by multiple criteria, namely for instance by the second and third elements in a tuple, let

data = [(1,2,3),(1,2,1),(1,1,4)]

and so define a lambda that returns a tuple that describes priority, for instance

sorted(data, key=lambda tup: (tup[1],tup[2]) )
[(1, 1, 4), (1, 2, 1), (1, 2, 3)]

Solution 4

I just want to add to Stephen's answer if you want to sort the array from high to low, another way other than in the comments above is just to add this to the line:

reverse = True

and the result will be as follows:

data.sort(key=lambda tup: tup[1], reverse=True)

Solution 5

In order to sort a list of tuples (<word>, <count>), for count in descending order and word in alphabetical order:

data = [
('betty', 1),
('bought', 1),
('a', 1),
('bit', 1),
('of', 1),
('butter', 2),
('but', 1),
('the', 1),
('was', 1),
('bitter', 1)]

I use this method:

sorted(data, key=lambda tup:(-tup[1], tup[0]))

and it gives me the result:

[('butter', 2),
('a', 1),
('betty', 1),
('bit', 1),
('bitter', 1),
('bought', 1),
('but', 1),
('of', 1),
('the', 1),
('was', 1)]
Share:
838,047
Stan
Author by

Stan

Updated on July 21, 2022

Comments

  • Stan
    Stan almost 2 years

    I have some data either in a list of lists or a list of tuples, like this:

    data = [[1,2,3], [4,5,6], [7,8,9]]
    data = [(1,2,3), (4,5,6), (7,8,9)]
    

    And I want to sort by the 2nd element in the subset. Meaning, sorting by 2,5,8 where 2 is from (1,2,3), 5 is from (4,5,6). What is the common way to do this? Should I store tuples or lists in my list?

    • Matthew Flaschen
      Matthew Flaschen almost 14 years
      With regard to "Should I store tuples or lists in my list?", a rule of thumb is to make things as immutable as possible. If you don't need to modify the sublists in place, make them tuples.
  • mechanical_meat
    mechanical_meat about 12 years
    So this answer is useful for Python 2.3-? Are there any valid uses in more-current Python versions around which you might elaborate a bit? If not, no bother...was just passing by, saw this and the old noggin got to churning just a wee bit. Anyway, cheers and thanks for this walk back into the earlier days of Python.
  • billwild
    billwild over 11 years
    Any idea how to sort it bigger to smaller?
  • Stephen
    Stephen over 11 years
    @billwild : help(sorted). reverse=True.
  • Joschua
    Joschua about 11 years
    @Stephen using itemgetter is faster and simpler: key=itemgetter(1) and at the beginning of the file: from operator import itemgetter
  • Neurotransmitter
    Neurotransmitter almost 8 years
    @Cemre as for the second example, sort here is a method of List object of Python, which receives a lambda function as its key parameter. You may name it as tup, or t, or whatever you like and it'll still work. tup here specifies index of the list's tuple, so 1 means that sorting will be performed by the second values of tuples from the original list (2, 5, 8).
  • Cecil Curry
    Cecil Curry over 7 years
    I was mildly sceptical of the unsubstantiated claim that "using itemgetter is faster and simpler." While I subjectively regard the intuitive lambda approach to be simpler than the unintuitive itemgetter class, itemgetter does indeed appear to be faster. I'm curious as to why this is. My crude suspicion is that a lambda incurs the hidden cost of capturing all local variables into a closure context, whereas an itemgetter instance does not. tl;dr: Always use itemgetter, because speed wins.
  • Cecil Curry
    Cecil Curry over 7 years
    This should be the accepted answer. See also Charlie's posted timings, demonstrating the itemgetter class to sort 126% faster on average than the equivalent lambda function.
  • Michael Ohlrogge
    Michael Ohlrogge almost 7 years
    You can also sort by multiple indices hierarchically, e.g. data.sort(key=itemgetter(3,1))
  • jdhao
    jdhao over 5 years
    I have done a more thorough benchmark between lambda and itemgetter used in sort here. itemgetter is always faster than lambda.
  • eric
    eric over 4 years
    what if tup[1] is a string?
  • questionto42standswithUkraine
    questionto42standswithUkraine almost 4 years
    Please see the itemgetter sorting solution for varying reverse arguments for multiple columns here, you then need to arrange your sorting in multiple steps in a row: stackoverflow.com/questions/14466068/…
  • sanjay patel
    sanjay patel over 3 years
    What if have tuple [(2,'John'), (1, 'Simon'), (3, 'Rober')] and need to sort on - key1 ascending and key2 descending. Thanks.
  • Shital Shah
    Shital Shah over 2 years
    sorted creates new list. To do in-place sorting use .sort(key=...)
  • Edouard Thiel
    Edouard Thiel over 2 years
    First sort on key2, then on key1.