Sorting is an extremely common task performed on lists in Python in many applications. A website needs to sort a list of users accordingly to their name; an online shopping application might want to sort products based on their prices; a university portal might want to sort students according to their GPA; and so on.
In addition to this, some common algorithms out there that operate on lists require them to be sorted. The highly efficient binary search is a perfect example.
In Python, there are two ways to sort a list: one is using the
sort() method of lists, and the other is using the global
sorted() function. In this chapterm we shall discover both these ways in meticulous detail.
The most straightforward way to sort a list is to call
sort() on it, without any arguments.
It will sort all the items of the list in increasing order, also known as ascending order, or alphabetical order.
sort() method, as we already know, sorts a list by side effect. That is, it doesn't return a new sorted list; rather it sorts the list in place and returns
sort()method mutates the list it's called on.
Following we have a list of numbers that we want to print in increasing order:
nums = [4, 0, 1, 18, 6, -3, -50]
To do so, we would go on and call the
sort() method on this list and then print it:
nums = [4, 0, 1, 18, 6, -3, -50] nums.sort() print(nums)
nums in place, after which we refer back to it in order to print it.
Sorting in decreasing order
To sort a list in decreasing order, set the
reverse keyword argument to
As the name suggests, the
reverse keyword argument specifies whether to sort the list in reverse order i.e decreasing order. By default, it's
False and so the list doesn't get sorted in reverse order.
Below we sort the same list
nums above, this time in decreasing order:
nums = [4, 0, 1, 18, 6, -3, -50] nums.sort(reverse=True) print(nums)
Sorting with a key
sort() method can be provided one more keyword argument and that is
key specifies a function to be called on each element of the list being sorted to return a value to be used for comparison in the underlying sorting algorithm.
Let's see how it works.
Suppose we have a list of students, each represented using a tuple whose first item is the stundent's name and the second item is the student's age:
students = [("Mark", 20), ("James", 19), ("Sandra", 20), ("Bill", 21)]
Now let's say we want to sort this list based on the name of each student. Calling
sort(), as is, won't work in this case since each item is a tuple, and therefore can't be validly compared with another one.
What we need to do is to tell Python what to use in comparing two items. This is where
key comes in.
students = [("Mark", 22), ("James", 19), ("Sandra", 20), ("Bill", 21)] def get_age(student): return student students.sort(key=get_age) print(students)
We create a function
get_age() and pass that as
sort(). Now whenever an item in the list is compared against another (in the underlying sorting algorithm), this function is called on both of them and the names of the students retrieved, respectively.
Whichever student's age is smaller than the other one's, it gets ordered first.
We can use
key to sort lists in complex ways.
An example, sorting a list of co-ordinates based on their distances from the origin, is demonstrated below:
points = [(0, 5), (3, 5), (6, 6), (0, 0), (2, 9), (4, 12)] def distance(point): # pythagoras's theorem return (point ** 2 + point ** 2) ** 2 points.sort(key=distance) print(points)
Given a point (represented as a tuple of two items: the x co-ordinate followed by the y co-ordinate), the function
distance() returns its distance from the origin, computed using the very famous Pythagoreon Theorem.
This function is set as the
points.sort(). It's called by
sort() for each of the elements of
points, and then the comparison is made over the returned value, that is the distance of the respective point from the origin.
The point with the least amount of distance is put first, while the point with the largest distance is put last. In short,
points is sorted according to the distance of each point, in increasing order.
Here's the output:
Uptil this point in this chapter, we've been considering sorting examples using the
sort() method of lists. The
sort() method mutates a given list, and doesn't itself return anything.
This means that if we want to work with a sorted version of a list without modifying its original order, we have to do some additional work of copying the list.
In the code below, we ought to work with a sorted configuration of
nums, but at the same time, need its original order preserved. This is possible by first making a copy of
nums, and then sorting this copy:
nums = [8, 5, 1, 3, 0, 4, 4, 12, 19] nums2 = nums[:] nums2.sort() # work with nums2 print(nums2)
The thing is that, often times, this boilerplate can become frustrating — we want to quickly work with a list's sorted version, and then forget it later on; why create another list?
This is where
sorted() comes in.
sorted() function works exactly how
sort() does — there is no single difference in the syntax of both these methods, except for that the former doesn't mutate the original list — rather it returns a new list in a sorted configuration.
sorted()method is meant to rightaway return the sorted list, be it any order, using any key.
Here's a comparison of
|Return value||The list|
|Parameters||The list to sort, |
Let's consider a quick example:
We want to print out each element in a list
nums in increasing order, without modifying its original order. Obviously, this is much convenient using
nums = [8, 5, 1, 3, -19] for num in sorted(nums): print(num) print(nums)
[8, 5, 1, 3, -19]
The first five prints here are the elements of
nums in increasing order. Then the list
nums is printed to see whether it has been changed or not. As expected, it is untouched.