Attend FREE Webinar on Digital Marketing for Career & Business Growth Register Now
Fulfill Your Career Objectives

Take Our Free Counselling Session

  • This field is for validation purposes and should be left unchanged.

A Descriptive Guide on How to Use sorted() and sort() in Python

 / 
A Descriptive Guide on How to Use sorted() and sort() in Python

Python provides two methods for organizing and customizing various types of data into different data structures. We will cover the implementation of simple ordering and sorting of data structures in Python in this article, the difference between sort) (and sorted) (and the configuration of a complicated sort order.

Sorting is very easy in Python as the built-in functions do all the heavy lifting. All you need to do is understand how to implement these functions and play with them to suit your sorting needs.

Using the Sorted()

How To Sort a List?

How To Sort a List? Source – Afternerd

Sorting Numbers

Sorted() is used for sorting a list in Python. Take the following example in which we have defined a list of numbers and the numbers variables is used as an argument in the sorted() function.

>>>

>>> numbers = [6, 9, 3, 1]

>>> sorted(numbers)

[1, 3, 6, 9]

>>> numbers

[6, 9, 3, 1]

You will get a new, sorted list as an output of this. With this example, you will be able to understand the following important characteristics of sorted():

1. You don’t need to define the sorted() function. It is already built-in Python’s standard installation.

2. With the sorted(), you don’t have to add any parameters or arguments. It will sort the numbers from smallest to largest, i.e., in any ascending order.

3. The function does not change the original variable. The sorted() provides the list in ascending order without changing the original value.

4. When you call sorted() function, it returns the ordered list. This means that you can assign a variable to the output of sorted().

Want to know the path to become
a Data Science & Analytics Expert ?

Free eBook on
The Journey of a
Data Scientist

  • This field is for validation purposes and should be left unchanged.
>>>

>>> numbers = [6, 9, 3, 1]

>>> numbers_sorted = sorted(numbers)

>>> numbers_sorted

[1, 3, 6, 9]

>>> numbers

[6, 9, 3, 1]

Here, you will get numbers_sorted, a new variable containing the output of sorted(). If you want to get information on sorted(), you can try calling help() function:

>>>

>>> # Python 3

>>> help(sorted)

Help on built-in function sorted in module builtins:

sorted(iterable, /, *, key=None, reverse=False)

A custom key function can be supplied to customize the sort order, and the reverse flag can be set to request the result in descending order.

If you work in Python 2 and are moving on to Python 3, there are a couple of changes that you must be aware about:

1. There is no cmp parameter in sorted() function of Python 3. For introducing custom sorting logic, you have to use the key parameter. You have to use functools.cmp_to_key() for converting the cmp function of Python2 to the key function.

2. You need to pass reverse and key as keyword arguments. In Python 2, you could use them as positional arguments.

Here is an example that will help you understand the usage of sorted() n sets and tuples:

>>>

>>> numbers_tuple = (6, 9, 3, 1)

>>> numbers_set = {5, 5, 10, 1, 0}

>>> numbers_tuple_sorted = sorted(numbers_tuple)

>>> numbers_set_sorted = sorted(numbers_set)

>>> numbers_tuple_sorted

[1, 3, 6, 9]

>>> numbers_set_sorted

[0, 1, 5, 10]

Here you might have observed that even though you gave a tuple and a set as an input, the output was a list. This is because by definition, the sorted() function returns a new list. If you have to match the output to the input type, you have to cast the returned object to a new type. If you want to cast the output back to a set, you need to stay careful as the set is unordered by definition. Here is an example that can help you do the same:

>>>

>>> numbers_tuple = (6, 9, 3, 1)

>>> numbers_set = {5, 5, 10, 1, 0}

>>> numbers_tuple_sorted = sorted(numbers_tuple)

>>> numbers_set_sorted = sorted(numbers_set)

>>> numbers_tuple_sorted

[1, 3, 6, 9]

>>> numbers_set_sorted

[0, 1, 5, 10]

>>> tuple(numbers_tuple_sorted)

(1, 3, 6, 9)

>>> set(numbers_set_sorted)

{0, 1, 10, 5}

When you cast the value of the numbers_set_sorted to a set, the result is not ordered. However, the sorted order remains in the variable, numbers_tuple_sorted.

Sorting Strings

Sorting Strings

Sorting Strings Source – The Renegade Coder

The str types can sort strings similarly to iterables like tuples and lists. Here is an example showing how sorted() function is used for iterating every character and ordering them in the output:

>>>

>>> string_number_value = '34521'

>>> string_value = 'I like to sort'

>>> sorted_string_number = sorted(string_number_value)

>>> sorted_string = sorted(string_value)

>>> sorted_string_number

['1', '2', '3', '4', '5']

>>> sorted_string

[' ', ' ', ' ', 'I', 'e', 'i', 'k', 'l', 'o', 'o', 'r', 's', 't', 't']

The sorted() function sorts the string by treating it as a list and then iterating through every character. It is important to remember that sorted() will sort every character in a sentence, including the spaces.

To change this behavior and get the right output, you need to use the split() function. Here is an example:

>>>

>>> string_value = 'I like to sort'

>>> sorted_string = sorted(string_value.split())

>>> sorted_string

['I', 'like', 'sort', 'to']

>>> ' '.join(sorted_string)

‘I like sort to’

Here, you can see that the original sentence has been transformed into a list of words instead of treating it as a string. After this, the sorting of list takes place and the words are combined to form a string again.

Limitations of Python Sorting

When you are using Python for sorting values other than integers, you will be facing some odd behaviors and limitations.

Lists With Non-Comparable Data Types 

When you are working with different data types, there might arise a case when the sorted() function cannot compare the data types. So, when you use sorted() function on a list of non-comparable data, an error will be returned. Following is an example where we try to compare an int and a none which cannot be sorted as they are incompatible:

>>>

>>> mixed_types = [None, 0]

>>> sorted(mixed_types)

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

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

The TypeError shows that the values given cannot be sorted. The program is trying to use the less than operator (<) for putting the values in sorting order by checking out which value is lower. Here is another example of TypeError where you replicate the TypeError, the same error which arises when you try comparing non-comparable values:

>>>

>>> None < 0

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

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

The TypeError exception is raised when the list contains a value that cannot be compared. Consider this. Should the number 0 come before or after the word apple? However, if there is a combination of strings and integers in the iterable, a list of comprehension can be used for casting the iterables to the comparable data types. 

Take this example:

>>>

>>> mixed_numbers = [5, "1", 100, "34"]

>>> sorted(mixed_numbers)

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

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

>>> # List comprehension to convert all values to integers

>>> [int(x) for x in mixed_numbers]

[5, 1, 100, 34]

>>> sorted([int(x) for x in mixed_numbers])

[1, 5, 34, 100]

Every element present in the mixed_numbers has int() called on them for converting them into str values. Then, we can successfully compare every element using the sorted() function and provide a sorted output.

Python is capable of converting a value to another data type implicitly. Take the example below, where the result is a false statement which is converted to bool type where 1 is true and 0 is false.

>>>

>>> similar_values = [False, 0, 1, 'A' == 'B', 1 <= 0]

>>> sorted(similar_values)

[False, 0, False, False, 1]

This example can be used for understanding sort stability. When you sort equal values in Python, the original order is retained in the output. 

Now, when you are comparing strings, the case matters. You can sort the values of a list of strings in ascending order, which means alphabetically. Take a look at this example:

>>>

>>> names = ['Harry', 'Suzy', 'Al', 'Mark']

>>> sorted(names)

['Al', 'Harry', 'Mark', 'Suzy']

However, in Python, Unicode Code Point of the first letter is used for determining the order. This means when you are comparing Al and al, the result will not be the same. Here is an example where ord() is used for returning the first letter’s Unicode Code Point.

>>>

>>> names_with_case = ['harry', 'Suzy', 'al', 'Mark']

>>> sorted(names_with_case)

['Mark', 'Suzy', 'al', 'harry']

>>> # List comprehension for Unicode Code Point of first letter in each word

>>> [(ord(name[0]), name[0]) for name in sorted(names_with_case)]

[(77, 'M'), (83, 'S'), (97, 'a'), (104, 'h')]

The first character of each element is returned by name[0]. As you can see that the output has M first because even though a comes before M, the code point of a comes after M. If the first letter is the same, the second character is used for determining the order. This goes on till you reach the end of the string. Check this example:

>>>

>>> very_similar_strs = ['hhhhhd', 'hhhhha', 'hhhhhc','hhhhhb']

>>> sorted(very_similar_strs)

['hhhhha', 'hhhhhb', 'hhhhhc', 'hhhhhd']

If you have strings that have identical values with different lengths, the sorted() function will ascend them from shortest length to the largest length. Here is an example:

>>>

>>> different_lengths = ['hhhh', 'hh', 'hhhhh','h']

>>> sorted(different_lengths)

['h', 'hh', 'hhhh', 'hhhhh']

reverse Argument in sorted() 

For changing the behavior of sorting through the assigned Boolean, you have to use the reverse keyword argument. If you assign true to reverse, the sorting order will be descending.

>>>

>>> names = ['Harry', 'Suzy', 'Al', 'Mark']

>>> sorted(names)

['Al', 'Harry', 'Mark', 'Suzy']

>>> sorted(names, reverse=True)

['Suzy', 'Mark', 'Harry', 'Al']

To keep the order ascending, you can assign the False value. Check out the following example that will help you understand the reverse’s behavior:

>>>

>>> names_with_case = ['harry', 'Suzy', 'al', 'Mark']

>>> sorted(names_with_case, reverse=True)

['harry', 'al', 'Suzy', 'Mark']

>>> similar_values = [False, 1, 'A' == 'B', 1 <= 0]

>>> sorted(similar_values, reverse=True)

[1, False, False, False]

>>> numbers = [6, 9, 3, 1]

>>> sorted(numbers, reverse=False)

[1, 3, 6, 9]

sorted() With a key Argument

They key argument is used on every value present in the list for determining the order of the output. For example, you want to sort a list on the basis of the length of the string, shortest to longest. Here is how you can do it using the key argument:

>>>

>>> word = 'paper'

>>> len(word)

5

>>> words = ['banana', 'pie', 'Washington', 'book']

>>> sorted(words, key=len)

['pie', 'book', 'banana', 'Washington']

The len() returns the length of the string which is then used to sort the list in ascending order. You can also use the key argument for sorting by first letter where the entire string is converted into lower case:

>>>

>>> names_with_case = ['harry', 'Suzy', 'al', 'Mark']

>>> sorted(names_with_case)

['Mark', 'Suzy', 'al', 'harry']

>>> sorted(names_with_case, key=str.lower)

['al', 'harry', 'Mark', 'Suzy']

As you can see, the values haven’t been converted into lowercase because there is no manipulation in the original list. When the sorting is taking place, the key is called on every item in the list for determining the order. The original value will not be changed in the output.

Register For a
Free Webinar

Date: 23rd Jan, 2020 (Thursday)
Time: 3 PM (IST/GMT +5:30)
  • This field is for validation purposes and should be left unchanged.

When you are using the key argument, you will be facing the following limitations:

1. There can be only 1 argument than can be passed to the key argument in the function. 

2. The function where the key argument is used should be able to handle every value in the iterable.

Apart from this, the key argument is a powerful feature of Python that can be used with any user-defined or built-in functions for manipulating the order of the output. 

For example, if you want to sort a list using the last letter of the string, you need to define a function and use it. Take a look at this:

>>>

>>> def reverse_word(word):

...     return word[::-1]

...

>>> words = ['banana', 'pie', 'Washington', 'book']

>>> sorted(words, key=reverse_word)

['banana', 'pie', 'book', 'Washington']

To reverse the string, the syntax word[::-1] is used. The reverse_word() is applied to every element. 

Now, here you could have used a lambda function instead of writing a standalone function. A lambda is an inline anonymous function with no name. It executes just like function but it doesn’t have any statements. IN the following example, the lambda function is used to define key with no name. x is the argument of lambda and the operation performed on argument is x[::-1].

>>>

>>> words = ['banana', 'pie', 'Washington', 'book']

>>> sorted(words, key=lambda x: x[::-1])

['banana', 'pie', 'book', 'Washington']

x[::-1]  reverses the word for every element. As you can see, the original words have not been affected by the reversed output used for sorting. If you want to change the order of output as well, you can use the reverse keyword with the key argument.

>>>

>>> words = ['banana', 'pie', 'Washington', 'book']

>>> sorted(words, key=lambda x: x[::-1], reverse=True)

['Washington', 'book', 'pie', 'banana']

Using the .sort()

The .sort() function does more of less of the same thing as of sorted(). But there are two critical differences as highlighted by the help() documentation.

>>>

>>> # Python2

Help on method_descriptor:

sort(...)

    L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;

    cmp(x, y) -> -1, 0, 1

 

>>> # Python3

>>> help(list.sort)

Help on method_descriptor:

 

sort(...)

L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*

First of all, .sort() can only be used for lists as it is a method of list class. Second, it modifies the values and returns none. Take a look at the following example to understand the impact of these differences:

>>

>>> values_to_sort = [5, 2, 6, 1]

>>> # Try to call .sort() like sorted()

>>> sort(values_to_sort)

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

NameError: name 'sort' is not defined

>>> # Try to use .sort() on a tuple

>>> tuple_val = (5, 1, 3, 5)

>>> tuple_val.sort()

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

AttributeError: 'tuple' object has no attribute 'sort'

>>> # Sort the list and assign to new variable

>>> sorted_values = values_to_sort.sort()

>>> print(sorted_values)

None

>>> # Print original variable

>>> print(values_to_sort)

[1, 2, 5, 6]

There are two major differences that can be seen in this example:

1. The new variable can pass only a none type as .sort() has no ordered output.

2. The original order of the list is not maintained and the list of values_to_sort has been changed.

There are reverse and key arguments available for .sort() as well. Here is an example of sorting a list by the third word’s second letter and returning the list in reverse.

>>>

>>> phrases = ['when in rome', 

...     'what goes around comes around', 

...     'all is fair in love and war'

...     ]

>>> phrases.sort(key=lambda x: x.split()[2][1], reverse=True)

>>> phrases

['what goes around comes around', 'when in rome', 'all is fair in love and war']

As you can see, a lambda function is used for splitting every phrase in a list of words, finding the third word and then the second letter in that word.

sorted() vs .sort()

Sorted () vs Sort ()

Sorted () vs Sort () Source – Slide Player

Now that you have understood how sorted() and .sort() works, you need to understand when to use which. Take a look at this example:

There is a 5k race. Your task is to capture and sort the data. The data is the number of runner’s bib and the seconds they took to finish the race:

>>>

>>> from collections import namedtuple

>>> Runner = namedtuple('Runner', 'bibnumber duration')

Every time a runner touches the finish line, they will be added to the runners list. Since in the 5k race, not everyone starts at the same time, the first person to reach the finishing line might not be the fastest one:

>>>

>>> runners = []

>>> runners.append(Runner('2528567', 1500))

>>> runners.append(Runner('7575234', 1420))

>>> runners.append(Runner('2666234', 1600))

>>> runners.append(Runner('2425234', 1490))

>>> runners.append(Runner('1235234', 1620))

>>> # Thousands and Thousands of entries later...

>>> runners.append(Runner('2526674', 1906))

Now, the programmer has to figure out the top 5 runners that will get the prize and the list has to be sorted according to the fastest time. All you need to do is sort the list by duration and take the participants with the lowest time:

>>>

>>> runners.sort(key=lambda x: getattr(x, 'duration'))

>>> top_five_runners = runners[:5]

Now, as you can see that a lambda function is used in the key argument for taking each runner’s duration attribute.  .sort() is used for sorting the time. The variable, top_five_runners, is used for storing the first 5 elements after the sorting is done.

But now, they want to gift a gym bag to every 20th person who crosses the finishing line. This is not going to be easy as the list has been irreversibly changed. You cannot get the original list in the order the runner’s finished. In such case, .sort() is not the best option for you. If you are working on unimportant data, or you have a copy of the data, you can use the .sort().

So, instead of .sort(), you should have used the sorted() with the lambda function. Here is how you can do it:

>>>

>>> runners_by_duration = sorted(runners, key=lambda x: getattr(x, 'duration'))

>>> top_five_runners = runners_by_duration[:5]

Now that you have used the sorted(), the original data has not been overwritten and is still intact. To find every 20th person to reach the finish line can be done using the following:

>>>

>>> every_twentieth_runners = runners[::20]

So basically, both sorted() and .sort() give the same exact order can be used with key and reverse argument in the same fashion. However, when it comes to in-place modifications and output, both of them have different characteristics.

Register For a
Free Webinar

Date: 23rd Jan, 2020 (Thursday)
Time: 3 PM (IST/GMT +5:30)
  • This field is for validation purposes and should be left unchanged.

As .sort() can irreversibly overwrite data, make sure that you think through before using it any program or application functionality. 

To become an expert in sort functions, you need to practice with complex data types like nested iterables. You can try Timsort for understanding the implementation of open-source Python code for built-ins and sort algorithms. 

Final Thoughts

You can become a Python coding language master and a highly-skilled Python programmer with a Python programming course. Any aspiring programmer can learn from the basics of Python after the course and keep mastering Python.




Your Comment

Your email address will not be published.