Skip to content
Home » Sorting Lists with the sort and sorted Functions

Sorting Lists with the sort and sorted Functions

Spread the love

Today we’ll be talking about sorting lists. We’ll be using the sort method and the built-in sorted function.

If you prefer to watch the video version first, here it is:

Sorting Lists with the sort Function

One thing to keep in mind right from the beginning. Unlike in older versions of Python, we only can sort lists with all the elements of the same type. It is now impossible to sort lists with heterogenous elements. This is what happens if we try:

>>> lst = ['hi', 5, 'no', 3.12]
>>> lst.sort()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'int' and 'str'

But, still, we can sort lists with different types of numeric values, like ints and floats (but not complex numbers):

>>> lst = [2, 6.8, 3, 0.022, 3.4e-8]
>>> lst.sort()
>>> lst
[3.4e-08, 0.022, 2, 3, 6.8]

We can even use the boolean literals True and False. They are treated as 1 and 0 respectively:

>>> lst = [2, 6.8, 3, True, 0.022, False, 3.4e-8]
>>> lst.sort()
>>> lst
[False, 3.4e-08, 0.022, True, 2, 3, 6.8]

Here’s how a list of lists gets sorted. The elements are compared in the order they’re in:

>>> lst = [[3, 6], [3], [3, 4, 2], [3, 4]]
>>> lst.sort()
>>> lst
[[3], [3, 4], [3, 4, 2], [3, 6]]

How about a list of strings? Have a look at this:

>>> lst = ['1aA', '1Aa', 'A1a', 'Aa1', 'a1A', 'aA1']
>>> lst.sort()
>>> lst
['1Aa', '1aA', 'A1a', 'Aa1', 'a1A', 'aA1']

The characters are compared one by one. Capital letters come before small letters and if there are digits, they come before capital letters, so the order is: digits – capital letters – small letters.

Note that in strings the comparison occurs between the individual digits one by one, not the values of the numbers:

>>> lst = ['10', '11', '101']
>>> lst.sort()
>>> lst
['10', '101', '11']

Here’s another example:

>>> lst = ['can', 'CAR', 'cAt']
>>> lst.sort()
>>> lst
['CAR', 'cAt', 'can']

Your Panda3D Magazine

Make Awesome Games and Other 3D Apps

with Panda3D and Blender using Python.

Cool stuff, easy to follow articles.

Get the magazine here (PDF).

The key Argument

As capital letters come before small letters, ‘can’ is last instead of first. But we can pass a keyword argument called key and set it to str.casefold if we don’t want the case to matter:

>>> lst = ['can', 'CAR', 'cAt']
>>> lst.sort(key = str.casefold)
>>> lst
['can', 'CAR', 'cAt']

Alternatively you can set key to str.lower or str.upper so that the characters are converted to all lowercase or all uppercase respectively before they are compared. This conversion is used by the sort function, but it doesn’t permanently modify the strings in the list:

>>> lst = ['can', 'CAR', 'cAt']
>>> lst.sort(key = str.lower)
>>> lst
['can', 'CAR', 'cAt']
>>> 
>>> 
>>> lst = ['can', 'CAR', 'cAt']
>>> lst.sort(key = str.upper)
>>> lst
['can', 'CAR', 'cAt']

Lambda Expressions

You can also use the key with a lambda expression:

>>> lst = ['can', 'CAR', 'cAt']
>>> lst.sort(key = lambda x: x.lower())
>>> lst
['can', 'CAR', 'cAt']

Built-In Functions

You can assign a built-in function to key as well. Here’s how we can use the len function to sort the strings from shortest to longest:

>>> lst = ['from', 'to', 'between', 'for', 'opposite', 'under']
>>> lst.sort(key = len)
>>> lst
['to', 'for', 'from', 'under', 'between', 'opposite']

Custom Functions

And now a more complicated example. Suppose we want to sort the strings by the last character. We can define a function that returns the last character and assign it to the key argument:

>>> def last_character(s):
...     return s[-1]
... 
>>> lst = ['Greece', 'Brazil', 'Germany', 'Finland', 'Mexico', 'Canada', 'Peru']
>>> lst.sort(key = last_character)
>>> lst
['Canada', 'Finland', 'Greece', 'Brazil', 'Mexico', 'Peru', 'Germany']

Python Jumpstart Course

Learn the basics of Python, including OOP.

with lots of exercises, easy to follow

The course is available on Udemy.

Sorting in Descending Order

As you can see, it’s up to you how you sort the elements of your list. Up to now we’ve been using ascending order. If you want to sort your list in descending order, you should set the value of the reverse keyword argument to True:

>>> lst = [4, 2, 8, 3, 11, 5]
>>> lst.sort(reverse = True)
>>> lst
[11, 8, 5, 4, 3, 2] 
sorting lists in descending order

Exercise

And now a short exercise:

We have a list of 3-tuples:

coordinates = [(3, 5, 7), (4, 2, 6), (7, 1, 9), (3, 3, 7)]

The three values in each tuple are the x, y and z coordinates in 3-dimensional space. We want to sort the coordinates by the y-coordinate, which is the middle one, at index 1, in descending order.

Solution

OK, we could define a function and assign it to the key argument, but instead we’ll use a lambda expression. Here’s the solution:

>>> coordinates = [(3, 5, 7), (4, 2, 6), (7, 1, 9), (3, 3, 7)]
>>> coordinates.sort(key = lambda tup: tup[1], reverse = True)
>>> coordinates
[(3, 5, 7), (3, 3, 7), (4, 2, 6), (7, 1, 9)]

Blender Jumpstart Course

Learn the basics of 3D modeling in Blender.

step-by-step, easy to follow, visually rich

The course is available on Udemy and on Skillshare.

Sorting Lists with the sorted Function

When we use the sort function, the list is changed in place. The sort function modifies the list, but it returns None, so you shouldn’t use it in an assignment like this:

>>> lst = [1, 4, 2, 8, 5]
>>> lst = lst.sort()
>>> type(lst)
<class 'NoneType'>

As you can see, all you have achieved by assigning the result of the sort method to the list is that you lost the reference to the list. Instead, the list is now of type None.

But it’s also possible to sort a list without changing it in place. To this end we can use the built-in sorted function and pass the list as an argument to it. Let’s rewrite the previous example using the sorted function:

>>> lst = [1, 4, 2, 8, 5]
>>> sorted(lst)
[1, 2, 4, 5, 8]
>>> lst
[1, 4, 2, 8, 5]

This time the original list doesn’t change. You can assign the result of the sorted method to a variable and so you can save the sorted list without modifying the original one:

>>> nums = [3, 2, 8, 1, 9, 5]
>>> nums_asc = sorted(nums)
>>> nums_asc
[1, 2, 3, 5, 8, 9]
>>> nums_desc = sorted(nums, reverse = True)
>>> nums_desc
[9, 8, 5, 3, 2, 1]
>>> nums
[3, 2, 8, 1, 9, 5]

In the sorted function you can also set the key argument to a function and so determine how the sorting should be performed. Here’s an example. A slightly tougher one!

We have a list of friends:

>>> friends = ["old Jim Brown", 
...            "pretty but not too smart Jane Smith", 
...            "silly Mike Lee", 
...            "my little Sarah Dubois", 
...            "amazing Frankie Jackson"] 

The list contains descriptions of our friends. The last but one word in each description is the first name. Using the sorted function we want to sort the list by first names. Here’s how we can do it with a method defined beforehand:

>>> def first_name(description):
...     return description.split()[-2]
... 
>>> sorted(friends, key = first_name)
['amazing Frankie Jackson', 'pretty but not too smart Jane Smith', 'old Jim Brown', 'silly Mike Lee', 'my little Sarah Dubois']

And the same with a lambda:

>>> sorted(friends, key = lambda n: n.split()[-2])
['amazing Frankie Jackson', 'pretty but not too smart Jane Smith', 'old Jim Brown', 'silly Mike Lee', 'my little Sarah Dubois']


Spread the love

Leave a Reply