By Md. Sabuj Sarker | 12/4/2017 | General |Intermediate

Advanced Sorting in Python

Advanced Sorting in Python

Sorting is one of the most important operations in programming. If you are coding in C or similar languages, sorting could be a nightmare. But in modern programming languages sorting is very easy, and in Python it’s even easier. You just need to call the sort() method or the sorted() function on ordered collections or iterators, e.g. lists.

Of course, it’s a bit more complicated when you want to sort an ordered collection of custom objects instead of strings, numbers or other built-in comparable types of data. Again, you do not want to always get the default sorting behavior. You may have some custom sorting order even for those built-in comparable data types. For example, you may need to sort a string by what is at the end of it, i.e. file extensions, etc.

In this guide I am going to show you how to sort iterables of both custom and built-in objects in Python with custom requirements.

Before You Begin

This is not an introductory Python guide. So, you should check the list below before you begin:

  • You have to have some basic knowledge of Python.
  • You must have familiarity with Object Oriented Programming in Python.
  • You should have coded for sorting lists of numbers, strings, etc. before.

To get started to code you need to do the following things:

  • Make sure that you have Python 3 installed on your system and available from command line.
  • Make sure that you have a plain text editor, code editor, or IDE installed on your system to write and edit Python code.
  • Create or choose a directory where you want to put your Python scripts.
  • Create a file called sorting.py in your chosen directory.
  • Start a command line in your chosen directory and run sorting.py with the command: python3 sorting.py (this is to make sure that everything is alright).

Sorting Lists or Iterables Using sort() and sorted()

Let's say we have a list of numbers that we want to sort in ascending order.

arr = [4, 5, 7, 2, 1, 5000, 1503, 763, 0, 1]

To sort this in ascending order, we need to call the sort() method on the arr object.

arr = [4, 5, 7, 2, 1, 5000, 1503, 763, 0, 1]
arr.sort()
print(arr)

Outputs:

[0, 1, 1, 2, 4, 5, 7, 763, 1503, 5000]

If we want to sort that in descending order, we can pass a keyword argument named reverse with value True.

arr = [4, 5, 7, 2, 1, 5000, 1503, 763, 0, 1]
arr.sort(reverse=True)
print(arr)

Outputs:

[5000, 1503, 763, 7, 5, 4, 2, 1, 1, 0]

We can carry out the same task with the help of the sorted() function. This is not a method on a list object, instead it is a free function that can accept any iterable. It's characteristics can be summarized as:

  • sorted() can accept any type of iterable
  • The iterable can both be ordered or unordered
  • It can accept both mutable and non-mutable iterables
  • It does not mutate the iterable it is sorting, instead it returns a new list of objects in sorted order
arr = (4, 5, 7, 2, 1, 5000, 1503, 763, 0, 1)
arr_sorted = sorted(arr, reverse=True)
print(type(arr_sorted))
print(arr_sorted)

Outputs:

[5000, 1503, 763, 7, 5, 4, 2, 1, 1, 0]

Providing Custom Sorting Behavior

In the examples, we can sort numbers in ascending or descending order. But, what if we want to have even numbers first and then the odd numbers?

To save our soul we have another optional parameter left in both sort() and sorted(), and this is key. A key is a callable (functions, static methods, lambdas, callable objects) that accepts one object each time from the iterable. It returns a key corresponding to that object. Python sorts the iterable depending on that key. As we want even numbers first and odd numbers later, we are going to return 0 for evens and 1 for odds.

def key_fun(o):
   if o % 2 == 0:
       return 0
   else:
       return 1

arr = (4, 5, 7, 2, 1, 5000, 1503, 763, 0, 1)
arr_sorted = sorted(arr, key=key_fun)
print(arr_sorted)

Outputs:

[4, 2, 5000, 0, 5, 7, 1, 1503, 763, 1]

We did not produce key such that smaller even numbers will be at the beginning of the output list. Take this as your homework to create such a function.

Sorting Iterable of Custom Objects by Key Function

Let's say that we have an object of the class Person and we want to sort Person objects according to their age. So, let's define the class and crate some objects with it.

class Person:
   def __init__(self, name, age):
       self.__name = name
       self.__age = age

   @property
   def age(self):
       return self.__age

   def __str__(self):
       return "(" + self.__name + ", " + str(self.__age) + ")"

   def __repr__(self):
       return str(self)

def p_key_fun(o):
   return o.age

pl = [
   Person("Md. Sabuj Sarker", 28),
   Person("Mr. Aaron", 30),
   Person("Mr. Liran", 40),
   Person("Justt Arifin", 26)
]

pl_sorted = sorted(pl, key=p_key_fun)
print(pl_sorted)

Outputs:

[(Justt Arifin, 26), (Md. Sabuj Sarker, 28), (Mr. Aaron, 30), (Mr. Liran, 40)]

Sorting Iterable of Custom Objects by Object Comparison

sort() and sorted() use < operator on objects inside the iterable if any key callable is not provided. So, let's customize our object and provide it an lt magic method so that it feels comfortable when < is used to compare two objects.

class Person:
   def __init__(self, name, age):
       self.__name = name
       self.__age = age

   @property
   def age(self):
       return self.__age

   def __str__(self):
       return "(" + self.__name + ", " + str(self.__age) + ")"

   def __repr__(self):
       return str(self)

   def __lt__(self, other):
       return True if self.age < other.age else False


   pl = [
       Person("Md. Sabuj Sarker", 28),
       Person("Mr. Aaron", 30),
       Person("Mr. Liran", 40),
       Person("Justt Arifin", 26)
   ]

   pl_sorted = sorted(pl)
   print(pl_sorted)

Outputs:

[(Justt Arifin, 26), (Md. Sabuj Sarker, 28), (Mr. Aaron, 30), (Mr. Liran, 40)]

Notice that we haven't provided any key function to sort. It sorted properly without any key function and just by comparing the objects.

Let's try with the reverse argument set to True. The output is as follows:

[(Mr. Liran, 40), (Mr. Aaron, 30), (Md. Sabuj Sarker, 28), (Justt Arifin, 26)]

So, everything is working as expected.

Conclusion

Sorting is an unavoidable part of real life Python programming. You need to master it so that you never get stuck in arranging objects in your Python code. Read this guide again if need be and practice code as much as you can. I am going to write more guides for you on sorting in other languages. If you are interested in sorting in other languages, do not forget to check this blog regularly.

Need more Python? Check out Using Threads in Python or use our search to discover hundreds of Python SDKs and other code tools.

By Md. Sabuj Sarker | 12/4/2017 | General

{{CommentsModel.TotalCount}} Comments

Your Comment

{{CommentsModel.Message}}

Recent Stories

Top DiscoverSDK Experts

User photo
3355
Ashton Torrence
Web and Windows developer
GUI | Web and 11 more
View Profile
User photo
3220
Mendy Bennett
Experienced with Ad network & Ad servers.
Mobile | Ad Networks and 1 more
View Profile
User photo
3060
Karen Fitzgerald
7 years in Cross-Platform development.
Mobile | Cross Platform Frameworks
View Profile
Show All
X

Compare Products

Select up to three two products to compare by clicking on the compare icon () of each product.

{{compareToolModel.Error}}

Now comparing:

{{product.ProductName | createSubstring:25}} X
Compare Now