# Sorting Data in a List

List is a collection of data (of different data types), much like an array. Like any data structure or data set, data in the list doesn't necessarily be in any specific order.

At times, depending on the use case we get to order the data in a specific sequence (Ascending, Descending or Reverse).

There are couple of methods and functions for sorting the data in a list, which can be used depending on the use case.

• sort() method
• sorted() function
• reverse() method
• reversed() function
Let's have a look at each of these in detail.

## sort() method

Sort() method by default sorts the data in an ascending order. One important thing to remember about sort() method is that, it sorts the list in-place, meaning the list on which method is called would be sorted and the method would return None (no sorted list would be returned).

### Syntax

list.sort(<key=None>, <reverse=False>)

The two parameters key and reverse mentioned in the syntax are optional. None and False are considered by default for key and reverse parameters respectively.

If no parameters are passed to the sort method, list would be sorted in an ascending order by default.

Let's have a look at an example.

 1234 input_list = [4, 2, 5, 3, 1]input_list.sort()print(input_list) # [1, 2, 3, 4, 5]

This is the most common and straight forward example, where a list contains set of integers and using the sort() method modifies the list with the integers sorted in an ascending order.

Before looking at the other optional parameters of the sort method, let's see what happens if the list contains data of other data type than integer.

 12345 input_list = ["FOUR", "TWO", "FIVE", "THREE", "ONE"]input_list.sort()print(input_list) # ['FIVE', 'FOUR', 'ONE', 'THREE', 'TWO']

A list with string data would sort fine i.e., data would be sorted in alphabetical order.

So, how does the sort work if there is a mixed data types in a list. E.g.: both integer and string.

 123 input_list = [4, "TWO", 5, "THREE", 1]input_list.sort()

Trying to sort a list which contains the data of different types would throw a TypeError.

 TypeError: '<' not supported between instances of 'str' and 'int'

So, need to be cautious when using the sort method on a list where the data types of the elements are unknown.

### Optional Parameter - reverse

Let's now explore the use of the optional parameter 'reverse' first and then see the importance of 'key'.

As the name states, passing 'True' to the 'reverse' parameter would result in the output to be in the reverse order than the default i.e., Data in the list would be sorted in a descending order.

Let's take a look at the same example as above, but with reverse parameter set to True.

 1234 input_list = [4, 2, 5, 3, 1]input_list.sort(reverse=True)print(input_list) # [5, 4, 3, 2, 1]

 12345 input_list = ["FOUR", "TWO", "FIVE", "THREE", "ONE"]input_list.sort(reverse=True)print(input_list)# ['TWO', 'THREE', 'ONE', 'FOUR', 'FIVE']

In both the cases, the list is sorted in a descending order. TypeError would still remain when data of different types is present in the list.

### Optional Parameter - key

Optional parameter 'key' accepts a function as a parameter and the default value is None. This parameter becomes extremely helpful where there is a nested lists (or tuples as elements).

When a function is passed to the 'key' parameter, function is applied to each element and sorts the list based on the value returned.

This can be better understood with a simple example. Let's look at the below without passing the 'key' first.

 12345 input_list = [(5, 5), (20, 2), (15, 3), (35, 1), (25, 4)]input_list.sort()print(input_list)# [(5, 5), (15, 3), (20, 2), (25, 4), (35, 1)]

In the above example, a list contains all tuples, with each tuple containing two elements. When a sort() method is called, data would be sorted based on the first element of the tuples embedded by default.

By passing the function that returns the value of the element in the second element (i.e., index - 1), data would be sorted based the corresponding element.

 12345 input_list = [(5, 5), (20, 2), (15, 3), (35, 1), (25, 4)]input_list.sort(key=lambda x:x)print(input_list) # [(35, 1), (20, 2), (15, 3), (25, 4), (5, 5)]

In the above example, we are passing the lambda function that returns the element at the index - 1 for the list. This function is called for every element of the list and sorts the list in ascending order of the corresponding element.

Both the optional parameters key and reverse can be used at the same time as per the requirement.

 12345 input_list = [(5, 5), (20, 2), (15, 3), (35, 1), (25, 4)]input_list.sort(key=lambda x:x, reverse=True)print(input_list)# [(5, 5), (25, 4), (15, 3), (20, 2), (35, 1)]

Like we have seen earlier, if the data is of different data types, if the list contains a combination of lists and tuples as elements, TypeError would be thrown. To note, this would only happen with the default value for the 'key' parameter.

 1234 input_list = [(5, 5), (20, 2), (15, 3), (35, 1), [25, 4]]input_list.sort()print(input_list)

 TypeError: '<' not supported between instances of 'list' and 'tuple'

We are trying to compare a list with tuple with list, which is not supported. This can be partially avoided with the use of 'key' function.

 12345 input_list = [(5, 5), (20, 2), (15, 3), (35, 1), [25, 4]]input_list.sort(key=lambda x:x)print(input_list)# [(35, 1), (20, 2), (15, 3), [25, 4], (5, 5)]

No error occurs in this scenario, because the function passed for the key parameter retrieves the element in index '1' and compares. However, if the contents of the nested list or tuple are different for the index specified in the key function, the error would still occur.

 1234 input_list = [(5, 5), (20, 2), (15, 3), (35, 1), [25, "FOUR"]]input_list.sort(key=lambda x:x)print(input_list)

 TypeError: '<' not supported between instances of 'str' and 'int'

One final error scenario, before we move on to the other functions/methods is if the number of elements of the embedded list/tuples is not same, then the index specified in the key function must be not greater than the tuple/list that contains the minimum number of elements.

If not, index out of range error would occur.

 1234 input_list = [(5, 5), (20, 2, 3), (15, 3), (35, 1, 1), (25, 4)]input_list.sort(key=lambda x:x)print(input_list)

Tuples (5, 5), (15, 3) and (25, 4) only contain 2 elements and passing '2' as index in lambda function would result in error (as this function needs to be called for every element of a list on which sort() method is called).

 IndexError: tuple index out of range

Passing the lambda function (key=lambda x:x) with index as '1' would not result in an error.

Most of these scenarios for sort() method are also applicable for the sorted() function and not detailing again.

## sorted() function

Like sort() method, sorted() function also sorts the data in an ascending order by default.

Primarily there are couple of differences between the sort() method and sorted() function.
• sorted() function accepts an iterable as an input and returns the sorted list. It does not modify the list passed, whereas sort() method modifies the list in-place.
• sorted() function accepts any iterable (List, Tuple or Set) and returns the sorted list, where as the sort() method can only be used on Lists.

### Syntax

list = sorted(<iterable>, <key=None>, <reverse=False>)

Let's have a look at an example with by passing a list and a tuple having same data with the default parameters and see.

 12345678 input_list = [4, 2, 5, 3, 1]output_list = sorted(input_list)print(input_list) # [4, 2, 5, 3, 1]print(output_list) # [1, 2, 3, 4, 5]input_tuple = (4, 2, 5, 3, 1)output_list = sorted(input_tuple)print(input_tuple) # (4, 2, 5, 3, 1)print(output_list) # [1, 2, 3, 4, 5]

In the above example,
• Line - 2: We are passing a list to the sorted() function, with default values for both key and reverse parameters. sorted() function returns a list that is sorted in ascending order. And, no change to the input list.
• Line - 6: We are passing a tuple to the sorted() function, with default values for the remaining two parameters. sorted() function returns a list that is sorted in ascending order.
Like we have seen for the sort() method, data in the list/tuple that we are passing to sorted() function should contain data of a single data type. Otherwise, TypeError would be thrown.

### Optional Parameter - reverse

Let's now explore the use of the optional parameter 'reverse' first, functionality of this parameter would remain same as above. Passing 'True' to the 'reverse' parameter would result in the output to be in the reverse order than the default i.e., Data in the list would be sorted in a descending order.

Let's take a look at the same example as above, but with reverse parameter set to True.

 12345 input_list = [4, 2, 5, 3, 1]output_list = sorted(input_list, reverse=True)print(input_list)  # [4, 2, 5, 3, 1]print(output_list) # [5, 4, 3, 2, 1]

 1234567 input_list = ["FOUR", "TWO", "FIVE", "THREE", "ONE"]output_list = sorted(input_list, reverse=True)print(input_list)  # ['FOUR', 'TWO', 'FIVE', 'THREE', 'ONE']print(output_list) # ['TWO', 'THREE', 'ONE', 'FOUR', 'FIVE']

In both the cases, the list is sorted in a descending order. TypeError would still remain when data of different types is present in the list.

### Optional Parameter - key

Optional parameter 'key' accepts a function as a parameter and the default value is None. This parameter becomes extremely helpful where there is a nested lists (or tuples as elements).

When a function is passed to the 'key' parameter, function is applied to each element and sorts the list based on the value returned.

Let's get straight on to passing the lambda function for the key parameter.

By passing the function that returns the value of the element in the second element (i.e., index - 1), data would be sorted based the corresponding element.

 1234567 input_list = [(5, 5), (20, 2), (15, 3), (35, 1), (25, 4)]output_list = sorted(input_list, key=lambda x:x)print(input_list)# [(5, 5), (20, 2), (15, 3), (35, 1), (25, 4)]print(output_list)# [(35, 1), (20, 2), (15, 3), (25, 4), (5, 5)]

In the above example, we are passing the lambda function that returns the element at the index - 1 for the list. This function is called for every element of the list and sorts the list in ascending order of the corresponding element.

Functionality remains same as the sort() method (including any error scenarios  and not mentioning all of them here again.

## reverse() method

Using reverse parameter in sort() method or sorted() function helps in sorting the data in descending order. But, how do we just arrange the data in reverse order.

I'm sure the first easiest thing that comes to the mind is that "slicing" way by passing '-1' as the step which returns the list in reverse order.

 1234 input_list = [4, 2, 5, 3, 1]output_list = input_list[::-1]print(output_list) # [1, 3, 5, 2, 4]

There is a list method 'reverse()' which does this. This method modified the list in-place and return None.

 1234 input_list = [4, 2, 5, 3, 1]input_list.reverse()print(input_list) # [1, 3, 5, 2, 4]

reverse() method does not have any parameters and modifies the list on which method is called.

There is another function 'reversed()' which returns the reversed list instead of modifying the list in-place, it returns a 'reversed object' which can used as an iterator.

## reversed() function

reversed() function accepts any iterable (list, tuple or set) as a parameter and returns an iterable i.e., 'reversed object'. It does not modify the iterable passed.

 12345 input_tuple = (4, 2, 5, 3, 1)output_list = reversed(input_tuple)for element in output_list:   print(element)

If the output needs to be a list instead of reversed object, this function can be called with in the list() function, which would convert the reversed object to a list.

 1234 input_tuple = (4, 2, 5, 3, 1)output_list = list(reversed(input_tuple))print(output_list) # [1, 3, 5, 2, 4]

I hope this post has provided a good insight on different ways of sorting data in a List.

As my first attempt I have also created video with the same information on different ways of sorting data in Python. Feel free to have a look and your valuable feedback is highly appreciated. 