Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sorting a list of tuples in Python

Tags:

python

While working on a problem from Google Python class, I formulated following result by using 2-3 examples from Stack overflow-

def sort_last(tuples):
    return [b for a,b in sorted((tup[1], tup) for tup in tuples)]

print sort_last([(1, 3), (3, 2), (2, 1)])

I learned List comprehension yesterday, so know a little about list comprehension but I am confused how this solution is working overall. Please help me to understand this (2nd line in function).

like image 600
Varun Avatar asked Apr 18 '12 16:04

Varun


People also ask

Can you sort tuples in Python?

In Python, use the sorted() built-in function to sort a Tuple. The tuple should be passed as an argument to the sorted() function. The tuple items are sorted (by default) in ascending order in the list returned by the function.

How do you sort a list of tuples by multiple elements?

To sort a list of tuples by multiple elements in Python: Pass the list to the sorted() function. Use the key argument to select the elements at the specific indices in each tuple. The sorted() function will sort the list of tuples by the specified elements.

How do you sort a tuple in Python without sorting?

You can use one of the easiest sorting algorithm that is bubble sort. In case of tuples in tuple it will sort in order of first element of tuple. So ((32, "b"), (1, "c"), (23,"a")) Now if you sort it it will sort it in the order of 1st element of tuple.


2 Answers

That pattern is called decorate-sort-undecorate.

  1. You turn each (1, 3) into (3, (1, 3)), wrapping each tuple in a new tuple, with the item you want to sort by first.
  2. You sort, with the outer tuple ensuring that the second item in the original tuple is sorted on first.
  3. You go back from (3, (1, 3)) to (1, 3) while maintaining the order of the list.

In Python, explicitly decorating is almost always unnecessary. Instead, use the key argument of sorted:

sorted(list_of_tuples, key=lambda tup: tup[1]) # or key=operator.itemgetter(1)

Or, if you want to sort on the reversed version of the tuple, no matter its length:

sorted(list_of_tuples, key=lambda tup: tup[::-1]) 
                              # or key=operator.itemgetter(slice(None, None, -1))
like image 97
agf Avatar answered Oct 02 '22 05:10

agf


Lets break it down:

In : [(tup[1],tup) for tup in tuples]

Out: [(3, (1, 3)), (2, (3, 2)), (1, (2, 1))]

So we just created new tuple where its first value is the last value of inner tuple - this way it is sorted by the 2nd value of each tuple in 'tuples'.

Now we sort the returned list:

In: sorted([(3, (1, 3)), (2, (3, 2)), (1, (2, 1))])

Out: [(1, (2, 1)), (2, (3, 2)), (3, (1, 3))]

So we now have our list sorted by its 2nd value of each tuple. All that is remain is to extract the original tuple, and this is done by taking only b from the for loop.

The list comprehension iterates the given list (sorted([...] in this case) and returns the extracted values by order.

like image 37
roeiba Avatar answered Oct 02 '22 07:10

roeiba