Sort a list of tuples by 2nd item (integer value)
PythonListTuplesPython Problem Overview
I have a list of tuples that looks something like this:
[('abc', 121),('abc', 231),('abc', 148), ('abc',221)]
I want to sort this list in ascending order by the integer value inside the tuples. Is it possible?
Python Solutions
Solution 1 - Python
Try using the key
keyword with sorted()
.
sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)],
key=lambda x: x[1])
key
should be a function that identifies how to retrieve the comparable element from your data structure. In your case, it is the second element of the tuple, so we access [1]
.
For optimization, see jamylak's response using itemgetter(1)
, which is essentially a faster version of lambda x: x[1]
.
Solution 2 - Python
>>> from operator import itemgetter
>>> data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]
>>> sorted(data,key=itemgetter(1))
[('abc', 121), ('abc', 148), ('abc', 221), ('abc', 231)]
IMO using itemgetter
is more readable in this case than the solution by @cheeken. It is
also faster since almost all of the computation will be done on the c
side (no pun intended) rather than through the use of lambda
.
>python -m timeit -s "from operator import itemgetter; data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]" "sorted(data,key=itemgetter(1))"
1000000 loops, best of 3: 1.22 usec per loop
>python -m timeit -s "data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]" "sorted(data,key=lambda x: x[1])"
1000000 loops, best of 3: 1.4 usec per loop
Solution 3 - Python
Adding to Cheeken's answer, This is how you sort a list of tuples by the 2nd item in descending order.
sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)],key=lambda x: x[1], reverse=True)
Solution 4 - Python
As a python neophyte, I just wanted to mention that if the data did actually look like this:
data = [('abc', 121),('abc', 231),('abc', 148), ('abc',221)]
then sorted()
would automatically sort by the second element in the tuple, as the first elements are all identical.
Solution 5 - Python
For an in-place sort, use
foo = [(list of tuples)]
foo.sort(key=lambda x:x[0]) #To sort by first element of the tuple
Solution 6 - Python
From python wiki:
>>> from operator import itemgetter, attrgetter
>>> sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
>>> sorted(student_objects, key=attrgetter('age'))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Solution 7 - Python
For a lambda-avoiding method, first define your own function:
def MyFn(a):
return a[1]
then:
sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=MyFn)
Solution 8 - Python
For Python 2.7+
, this works which makes the accepted answer slightly more readable:
sorted([('abc', 121),('abc', 231),('abc', 148), ('abc',221)], key=lambda (k, val): val)
Solution 9 - Python
The fact that the sort values in the OP are integers isn't relevant to the question per se. In other words, the accepted answer would work if the sort value was text. I bring this up to also point out that the sort can be modified during the sort (for example, to account for upper and lower case).
>>> sorted([(121, 'abc'), (231, 'def'), (148, 'ABC'), (221, 'DEF')], key=lambda x: x[1])
[(148, 'ABC'), (221, 'DEF'), (121, 'abc'), (231, 'def')]
>>> sorted([(121, 'abc'), (231, 'def'), (148, 'ABC'), (221, 'DEF')], key=lambda x: str.lower(x[1]))
[(121, 'abc'), (148, 'ABC'), (231, 'def'), (221, 'DEF')]