There are two main ways to sort a list of strings in Python – using the built-in sort()
function and the built-in sorted()
function.
We’ll discuss how to use each function in today’s post and the differences between the two. In addition, we’ll talk about different ways to modify the sort criteria. By default, both functions sort the strings using Unicode code points, in ascending order. If you want to sort using some other criteria, you need to pass additional arguments to the functions. We’ll learn to do that later.
Last but not least, we’ll work on a practice question where we’ll write a function that accepts a list of names (with first names and last names) and sorts the list based on last names.
Here are some topics we’ll cover in today’s post:
- How to use the built-in
sort()
function - How to use the built-in
sorted()
function - Differences between the
sort()
andsorted()
function - How to modify the sort criteria
- How to use lambda functions
- How to split a string into substrings
Table of Contents
How to sort a list using the sort() function
The sort()
function is a built-in function in Python that sorts a list in ascending order. The syntax of the function is as follows:
<list_to_sort>.sort(reverse, key)
The function accepts two arguments – reverse
and key
, both of which are optional and are used to define the sort criteria. We’ll learn to use them later.
Using sort() without arguments
Let’s first learn to use the sort()
function without arguments.
Example 1
fruits = ['cherry', 'apple', 'fig', 'date', 'banana', 'grapes']
fruits2 = ['Banana', 'banana', 'apple']
numbers = ['12', '2', '1', '500', '9']
fruits.sort()
fruits2.sort()
numbers.sort()
print(fruits)
print(fruits2)
print(numbers)
In the examples above, we first declare three lists called fruits
, fruits2
and numbers
. Next, we use the lists to call the sort()
function. If you run the code above, you’ll get the following output:
['apple', 'banana', 'cherry', 'date', 'fig', 'grapes']
['Banana', 'apple', 'banana']
['1', '12', '2', '500', '9']
The output for fruits
is self-explanatory; the list is sorted alphabetically in ascending order.
The output for fruits2
, on the other hand, illustrates that the sort()
function is case-sensitive. As lowercase letters have greater Unicode code points than uppercase letters, they are considered to be greater than uppercase letters. Hence, 'Banana'
comes before 'apple'
as 'a'
is considered to be greater than 'B'
.
Finally, the output for numbers
shows how the sort()
function sorts strings of numbers; it sorts them based on corresponding digits in the strings.
For instance,'12'
comes before '2'
, '500'
and '9'
in the sorted list as the first digit in '12'
(i.e. '1'
) is smaller than the first digits in '2'
, '500'
and '9'
. Hence, '12'
is considered to be smaller than the latter strings. The same applies to '500'
. Although 500 is numerically greater than 9, its first digit ('5'
) is smaller than '9'
. Hence, '500'
comes before '9'
in the resulting list.
Using the key argument to define the sort criteria
Next, let’s look at how we can alter the criteria used by the sort()
function for sorting.
By default, the sort()
function sorts strings using Unicode code points. If we want to use some other criteria for sorting, we can use the key
argument. To do that, we assign the name of a function to the argument.
Let’s look at some examples.
Example 2: Sorting based on length of strings (use the len() function)
To sort strings based on their lengths, we can assign len
to the key
argument. This tells Python to sort the list based on the result of the built-in len()
function.
fruits = ['cherry', 'apple', 'fig', 'date', 'banana', 'grapes']
fruits.sort(key=len)
print(fruits)
If you run the code above, you’ll get the following output:
['fig', 'date', 'apple', 'cherry', 'banana', 'grapes']
Example 3: Sorting based on numerical value of strings (use the int() or float() function)
If we want to sort strings of numbers based on their numerical values, we can assign int
or float
to the key
argument.
numbers = ['12', '2', '1', '500', '9']
numbers.sort(key=int)
print(numbers)
Here, we sort the numbers
list based on the result of the int()
function. Since the int()
function casts a string to an integer, the numbers
list will be sorted based on the values of the resulting integers.
Hence, we’ll get the following output if we run the code above:
['1', '2', '9', '12', '500']
Example 4: Sorting based on user-defined function
Besides sorting based on the results of built-in functions, we can define our own function and use its result to sort our list. For instance, if we want to sort the strings based on the number of times ‘e’ appears in the string, we can use the code below:
def numberOfe(myStr):
return myStr.count('e')
myList = ['cosmology', 'therefore', 'three', 'apple', 'zebra', 'yesterday']
myList.sort(key=numberOfe)
print(myList)
Here, we first declare a function called numberOfe()
that accepts one argument – myStr
. Inside the function, we use the built-in count() function to count the number of times ‘e’ appears in myStr
and use the return
statement to return the answer.
Next, we declare a list called myList
on line 4.
On line 6, we use the sort()
function to sort myList
, based on the result returned by numberOfe()
.
Finally, on line 7, we print the resulting list.
If you run the code above, you’ll get the following output:
['cosmology', 'apple', 'zebra', 'three', 'yesterday', 'therefore']
The strings in myList
are sorted in ascending order based on the number of times ‘e’ appeared in the string.
Example 5: Sorting based on lambda function
In the example above, the numberOfe()
function is a very simple function that only returns a value. In cases like that, we can use a lambda function.
A lambda function refers to an anonymous function (i.e. a function without a name) that can only evaluate one expression. We’ve looked at lambda functions previously when we discussed the max()
function in Python. If you are unfamiliar with lambda functions, you should definitely check out that post.
Similar to the max()
function, we can use lambda functions with the sort()
function. An example is shown below:
myList = ['cosmology', 'therefore', 'three', 'apple', 'zebra', 'yesterday']
myList.sort(key = lambda myStr : myStr.count('e'))
print(myList)
Here, the lambda function is
lambda myStr : myStr.count('e')
This function states that for every input string myStr
, return the result of myStr.count('e')
.
This function performs the same task as the numberOfe()
function, but does that with only one line of code.
When we assign this function to the key
argument, we achieve the same outcome as Example 4 above. If we run the code, we’ll get the following output:
['cosmology', 'apple', 'zebra', 'three', 'yesterday', 'therefore']
Using the reverse argument to sort in descending order
Next, let’s look at another optional argument for the sort()
function – the reverse
argument.
This function allows us to sort a list in descending order (the default order is ascending). Let’s look at an example:
Example 6:
fruits = ['cherry', 'apple', 'fig', 'date', 'banana', 'grapes']
fruits.sort(key=len, reverse=True)
print(fruits)
In the example above, we want to sort fruits
in descending order, based on the length of the strings. To do that, we pass reverse = True
(to reverse the order) and key = len
to the sort()
function.
If you run the code above, you’ll get the following output.
['cherry', 'banana', 'grapes', 'apple', 'date', 'fig']
'cherry'
, 'banana'
and 'grapes'
come first as they all have a length of 6.
'apple'
comes next with a length of 5, followed by 'date'
with a length of 4 and 'fig'
with a length of 3.
How to sort a list using the sorted() function
We’ve looked at various examples of how to use the sort()
function to sort a list of strings in Python.
Next, let’s look at how we can sort a list of strings using another built-in function – sorted()
.
This function is very similar to the sort()
function. Its syntax is shown below:
sorted(<list_to_sort>, key, reverse)
The function sorts a list in ascending order and returns a new list with the sorted result.
key
and reverse
work in the same way as their counterparts in the sort()
function and are both optional.
Let’s look at some examples:
Example 7:
fruits = ['cherry', 'apple', 'fig', 'date', 'banana', 'grapes']
#sort in ascending order
new_fruits = sorted(fruits)
print(new_fruits)
#sort in descending order
new_fruits = sorted(fruits, reverse = True)
print(new_fruits)
#sort based on length
new_fruits = sorted(fruits, key=len)
print(new_fruits)
Here, we show three examples of using the sorted()
function.
If you run the code above, you’ll get the following output:
['apple', 'banana', 'cherry', 'date', 'fig', 'grapes']
['grapes', 'fig', 'date', 'cherry', 'banana', 'apple']
['fig', 'date', 'apple', 'cherry', 'banana', 'grapes']
Differences between the sort() and sorted() functions
As you can see from the example above, the sorted()
function is very similar to the sort()
function. However, there are three main differences between the two functions, as shown in the table below:
sort() | sorted() |
---|---|
To call the function, use the dot (.) operator | To call the function, pass the list as the first argument to the function |
Modifies the list used to call the function | Does not modify the list. Instead, it returns a new list with the sorted result |
Can only be used to sort lists | Can be used to sort any iterable (such as tuples and dictionaries) |
Firstly, to call the sort()
function, we use the dot operator. For instance, to sort a list called names
, we write names.sort()
. In contrast, to call the sorted()
function, we pass the list as an argument to the function. For instance, to sort names
, we write sorted(names)
.
Next, the sort()
function modifies the list that we use to call the function. When we write names.sort()
, the function modifies the names
list itself and does not return any result. We say that the sort()
function sorts the names
list in-place.
In contrast, the sorted()
function does not modify the list we pass to it. Instead, it creates and returns a new list with a sorted version of the list we pass to it.
To illustrate what this means, let’s look at the following example:
#Using the sort() function
names = ['John', 'Matt', 'Vicky', 'Aaron', 'Caleb']
names_result = names.sort()
print(names)
print(names_result)
If you run the code above, you’ll get the following output:
['Aaron', 'Caleb', 'John', 'Matt', 'Vicky']
None
Line 1 in the output above shows that names
is modified after we use it to call the sort()
function. Line 2 shows that the sort()
function does not return any result. Hence, we get None
when we try to print the result of the sort()
function (which we store in a variable called names_result
.
Next, let’s see what happens when we use the sorted()
function.
#Using the sorted() function
names2 = ['John', 'Matt', 'Vicky', 'Aaron', 'Caleb']
names2_result = sorted(names2)
print(names2)
print(names2_result)
If you run the code above, you’ll get the following output:
['John', 'Matt', 'Vicky', 'Aaron', 'Caleb']
['Aaron', 'Caleb', 'John', 'Matt', 'Vicky']
Line 1 in the output above shows that names2
is not modified after we pass it to the sorted()
function. Line 2 gives us the sorted version of names2
(which we store in a variable called names2_result
).
Last but not least, the sort()
function can only be used to sort lists. This is because it belongs to the list class. In contrast, the sorted()
function does not belong to the list class and can be used to sort other iterables, such as a tuple or dictionary.
For instance,
months = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun')
#Using sorted() to sort tuple
new_months = sorted(months)
print(new_months)
#Using sort() to sort tuple
months.sort()
print(months)
gives us the following output:
['Apr', 'Feb', 'Jan', 'Jun', 'Mar', 'May']
Traceback (most recent call last):
File "...", line ..., in <module>
months.sort()
AttributeError: 'tuple' object has no attribute 'sort'
While the sorted()
function can be used to sort the months
tuple (first line in the output above), the sort()
function cannot and gives us an error.
Practice Question
Now that you are familiar with the sort()
and sorted()
functions, let’s apply what we’ve learned on a practice question.
This practice question requires us to write a function called sortLastNames()
that accepts a list of strings containing names.
The names are of the following format: first name, followed by a space and last name. An example is 'John Parkson'
, where 'John'
is the first name and 'Parkson'
is the last name.
The function needs to return a new list where the names are sorted based on last names. The original list should not be modified.
Expected Result
To test your function, you can run the following statements:
names = ['Peter Jones', 'James Lee', 'Larry Yang', 'Matt Armstrong']
new_names = sortLastNames(names)
print(names)
print(new_names)
You should get the following output:
['Peter Jones', 'James Lee', 'Larry Yang', 'Matt Armstrong']
['Matt Armstrong', 'Peter Jones', 'James Lee', 'Larry Yang']
Here, we call the sortLastNames()
function using names
as the argument and assign the result to a new list called new_names
.
When we print the values of names
and new_names
, the original list – names
– is not modified.
The new list new_names
is sorted based on last names. 'Matt Armstrong'
comes first as the last name starts with 'A'
, which is smaller than 'J'
, 'L'
and 'Y'
.
Suggested Solution
Here’s the suggested solution for today’s practice question:
def sortLastNames(names):
return sorted(names, key = lambda x : x.split(' ')[1])
This function uses a lambda function to define the sort criteria. This lambda function has one argument x
and returns the value of x.split(' ')[1]
.
split()
is a built-in function in Python for splitting strings into a list of substrings.
split(' ')
splits the string into substrings using ' '
(i.e. a space) as the delimiter.
For instance, suppose we have a string called myStr
with the value 'Python is fun and easy'
.
myStr.split(' ')
splits the string into the list ['Python', 'is', 'fun', 'and', 'easy']
.
myStr.split(' ')[1]
gives us the second element (index = 1) in the resulting list. In other words, it gives us the substring 'is'
.
In our lambda function, x.split(' ')[1]
gives us the second element in x
(which corresponds to the last name if x
is a name). Hence, the names
list is sorted based on last names, which is what we want. We use the return
keyword to return the result of the sorted list.
If you are not comfortable with lambda functions, here’s an alternative solution that uses a named function to achieve the same result:
def getLastName(x):
return x.split(' ')[1]
def sortLastNames(names):
return sorted(names, key=getLastName)
Here, we define a function called getLastName()
to get the second word (which corresponds to the last name) in the input string x
.
Next, we assign this function to the key
argument when calling the sorted()
function on line 5 and use the return
statement to return the sorted list.
Both suggested solutions work the same way, the only difference is one uses a lambda function (and hence fewer lines) while the other uses a named function. Either way is fine.