Every computer scientist loves sorting things. In this article, I’ll show you how you can modify the default Python sorting behavior with the key argument.
Definition and Usage: To customize the default sorting behavior of the list.sort()
and sorted()
method, use the optional key
argument by passing a function that returns a comparable value for each element in the list.
Here’s a short overview example that shows you how to use the arguments in practice:
# Create an unsorted integer list lst = [88, 12, 42, 11, 2] # Sort the list in place (ascending) lst.sort() print(lst) # [2, 11, 12, 42, 88] # Sort the list (leading number) lst.sort(key=lambda x: str(x)[0]) print(lst) # [11, 12, 2, 42, 88]
In the first line of the example, you create the list lst
. You then sort the list once using the default sorting behavior and once using a customized sorting behavior with only the first letter of the number.
Code Puzzle — Try It Yourself:
Now you know the basics. Let’s deepen your understanding with a short code puzzle—can you solve it?
You can also solve this puzzle and track your Python skills on our interactive Finxter app.
Syntax: You can call this method on each list object in Python (Python versions 2.x and 3.x). Here’s the syntax:
list.sort(key=None, reverse=False)
Arguments:
Argument | Description |
---|---|
key | (Optional. Default None .) Pass a function that takes a single argument and returns a comparable value. The function is then applied to each element in the list. Then, the method sorts based on the key function results rather than the elements themselves. |
reverse | (Optional. Default False .) The order of the list elements. If False , sorting is in ascending order. If True , it’s in descending order. |
Related articles:
- Python List Methods [Overview]
- Python List sort() – The Ultimate Guide
- Python Lists – Everything You Need to Know to Get Started
Python List Sort Key
The list.sort()
method takes another function as an optional key
argument that allows you to modify the default sorting behavior. The key function is then called on each list element and returns another value based on which the sorting is done. Hence, the key function takes one input argument (a list element) and returns one output value (a value that can be compared).
Here’s an example:
>>> lst = [(1,2), (3,2), (3,3), (1,0), (0,1), (4,2), (1,1), (0,2), (0,0)] >>> lst.sort() >>> lst [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (3, 2), (3, 3), (4, 2)] >>> lst.sort(key=lambda x: x[0]) >>> lst [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (3, 2), (3, 3), (4, 2)] >>> lst.sort(key=lambda x: x[1]) >>> lst [(0, 0), (1, 0), (0, 1), (1, 1), (0, 2), (1, 2), (3, 2), (4, 2), (3, 3)]
You can see that in the first two examples, the list is sorted according to the first tuple value first. In the third example, the list is sorted according to the second tuple value first. You achieve this by defining a key function key=lambda x: x[1]
that takes one list element x
(a tuple) as an argument and transforms it into a comparable value x[1]
(the second tuple value).
Related article:
Python List Sort Key Lambda
Lambda functions are anonymous functions that are not defined in the namespace (they have no names). In it’s simplest form, the syntax is:
lambda argument : expression.
You map the argument to the result of the expression.
You can use the lambda function syntax to define the key argument of the sort()
method in place.
Here’s an example:
>>> from operator import itemgetter >>> customers = [('alice', 1000), ('bob', 100), ('frank', 10)] >>> customers.sort(key=lambda x: x[1]) [('frank', 10), ('bob', 100), ('alice', 1000)]
The lambda function returns the second tuple value of each tuple in the list. This is the basis on which the sorting algorithm bases its order.
Python List Sort Default Key
If you don’t define a key argument for the list.sort()
or sorted()
methods, Python is still using a key function. So, what is the default key function?
Think about this for a moment: the meaning of a key function is to associated a “value” that can be used for comparison. So you should be able to perform the following comparison operations on the resulting key values.
What does it mean to be comparable? A comparable object must implement a number of methods (source):
Operator | Method |
---|---|
== | __eq__ |
!= | __ne__ |
< | __lt__ |
<= | __le__ |
> | __gt__ |
>= | __ge__ |
If you implement all of those methods, you can compare two elements easily. All basic Python data structures have implemented them. So don’t worry about it.
The default key function returns the list element itself. Thus, the list elements themselves are the basis of the comparison. The implemented comparison routines allow Python to compare each pair of list elements in order to find a sorted sequence.
Python List Sort Key Itemgetter
You can use any function as a key function that transforms one element into another (comparable) element.
For example, it’s common to use the itemgetter()
function from the operator
module to access the i-th value of an iterable:
>>> from operator import itemgetter >>> customers = [('alice', 1000), ('bob', 100), ('frank', 10)] >>> customers.sort(key=itemgetter(1)) [('frank', 10), ('bob', 100), ('alice', 1000)]
The itemgetter()
function does exactly the same as the lambda function in the previous example: it returns the second tuple value and uses it as a basis for comparison.
Python List Sort Secondary Key
How to sort a list with two keys? For example, you have a list of tuples [(1,2), (3,2), (3,3), (1,0), (0,1), (4,2), (1,1), (0,2), (0,0)]
and you want to sort after the second tuple value first. But if there’s a tie (e.g. (1,2)
and (3,2)
), you want to sort after the first tuple value. How can you do that?
Per default, Python sorts tuples lexicographically—the first tuple value is considered first. Only if there’s a tie, it takes the second tuple value and so on.
So to sort with “two keys”, you can define a key function that returns a tuple rather than only a single tuple value. Here’s an example:
>>> lst = [(1,2), (3,2), (3,3), (1,0), (0,1), (4,2), (1,1), (0,2), (0,0)] >>> lst.sort(key=lambda x: (x[1], x[0])) >>> lst [(0, 0), (1, 0), (0, 1), (1, 1), (0, 2), (1, 2), (3, 2), (4, 2), (3, 3)]
The second tuple value takes precedence over the first tuple value.
Python List Sort Key Len
Problem: Given a list of strings. How can you sort them by length?
Example: You want to sort your list of strings ['aaaa', 'bbb', 'cc', 'd']
by length—starting with the shortest string. Thus, the result should be ['d', 'cc', 'bbb', 'aaaa']
. How to achieve that?
Solution: Use the len()
function as key argument of the list.sort()
method like this: list.sort(key=len)
. As the len()
function is a Python built-in function, you don’t need to import or define anything else.
Here’s the code solution:
lst = ['aaaa', 'bbb', 'cc', 'd'] lst.sort(key=len) print(lst)
The output is the list sorted by length of the string:
['d', 'cc', 'bbb', 'aaaa']
You can also use this technique to sort a list of lists by length.
Python List Sort Key Reverse
To sort a list in ascending order means that the elements are ordered from small to large. Per default, Python lists are sorted in ascending order.
lst_1 = ['Bob', 'Alice', 'Frank'] lst_1.sort() print(lst_1) # ['Alice', 'Bob', 'Frank'] lst_2 = [10, 8, 11, 2, 1] lst_2.sort() print(lst_2) # [1, 2, 8, 10, 11]
However, if you want to sort in descending order (from large to small), you can use either of the following two methods:
- Use the
list.sort(reverse=True)
method with thereverse=True
argument. - Use slicing
list[::-1]
to reverse the order of the list.
The difference between both methods is that the first changes the list in place, and the second creates a new list with sorted elements in descending order.
Here’s the example:
lst_1 = ['Bob', 'Alice', 'Frank'] lst_1.sort(reverse=True) print(lst_1) # ['Frank', 'Bob', 'Alice'] lst_2 = [10, 8, 11, 2, 1] lst_2.sort() lst_2 = lst_2[::-1] print(lst_2) # [11, 10, 8, 2, 1]
As you see, using the reverse=True
argument is prettier in most cases.
Python List Sort Key Tuple
Problem: Say you have a list of tuples [(1,1,2), (0,0,1), (0,1,0), (0,1,2), (1,4,0)]
and you want to sort after the second tuple value first. But if there’s a tie (e.g. (0,1,0)
and (1,1,2)
), you want to sort after the third tuple value. If there’s another tie, you want to sort after the first tuple value. How can you do that?
Per default, Python sorts tuples lexicographically which means that the first tuple value is considered first. Only if there’s a tie, it takes the second tuple value and so on.
Solution: Define a key function that returns a tuple rather than only a single tuple value. Here’s an example:
>>> lst = [(1,1,2), (0,0,1), (0,1,0), (0,1,2), (1,4,0)] >>> lst.sort() >>> lst [(0, 0, 1), (0, 1, 0), (0, 1, 2), (1, 1, 2), (1, 4, 0)] >>> lst.sort(key=lambda x: (x[1],x[2],x[0])) >>> lst [(0, 0, 1), (0, 1, 0), (0, 1, 2), (1, 1, 2), (1, 4, 0)]
The second tuple value takes precedence over the third tuple value. And the third tuple value takes precedence over the first tuple value.
Python List Sort By Key in Dictionary
Next, you’re going to learn how to sort a list of dictionaries in all possible variations. [1] So let’s get started!
How to Sort a List of Dictionaries By Value?
Problem: Given a list of dictionaries. Each dictionary consists of multiple (key, value) pairs. You want to sort them by value of a particular dictionary key (attribute). How do you sort this dictionary?
Minimal Example: Consider the following example where you want to sort a list of salary dictionaries by value of the key 'Alice'
.
salaries = [{'Alice': 100000, 'Bob': 24000}, {'Alice': 121000, 'Bob': 48000}, {'Alice': 12000, 'Bob': 66000}] sorted_salaries = # ... Sorting Magic Here ... print(sorted_salaries)
The output should look like this where the salary of Alice determines the order of the dictionaries:
[{'Alice': 12000, 'Bob': 66000}, {'Alice': 100000, 'Bob': 24000}, {'Alice': 121000, 'Bob': 48000}]
Solution: You have two main ways to do this—both are based on defining the key function of Python’s sorting methods. The key function maps each list element (in our case a dictionary) to a single value that can be used as the basis of comparison.
- Use a lambda function as the key function to sort the list of dictionaries.
- Use the itemgetter function as the key function to sort the list of dictionaries.
Here’s the code of the first option using a lambda function that returns the value of the key 'Alice'
from each dictionary:
# Create the dictionary of Bob's and Alice's salary data salaries = [{'Alice': 100000, 'Bob': 24000}, {'Alice': 121000, 'Bob': 48000}, {'Alice': 12000, 'Bob': 66000}] # Use the sorted() function with key argument to create a new dic. # Each dictionary list element is "reduced" to the value stored for key 'Alice' sorted_salaries = sorted(salaries, key=lambda d: d['Alice']) # Print everything to the shell print(sorted_salaries)
The output is the sorted dictionary. Note that the first dictionary has the smallest salary of Alice and the third dictionary has the largest salary of Alice.
[{'Alice': 12000, 'Bob': 66000}, {'Alice': 100000, 'Bob': 24000}, {'Alice': 121000, 'Bob': 48000}]
Try It Yourself:
You’ll learn about the second way below (where you use the itemgetter
function from the operator
module).
Related articles on the Finxter blog:
Python List Sort JSON By Key
Problem: Given a JSON object as a list of dictionaries in Python. Sort the dictionary by value of a given attribute.
Example: Say, you have a list of JSON objects (e.g., a nested dictionary) and you want them to sort by JSON attribute 'access_time'
.
json = [{"page": { "url": "finxter.com", "access_time": "44"}}, {"page": { "url": "python.org", "access_time": "12"}}, {"page": { "url": "google.com", "access_time": "6"}}] # ... Sorting Magic Here ... print(json)
Your goal is the following result:
[{"page": { "url": "google.com", "access_time": "6"}}, {"page": { "url": "python.org", "access_time": "12"}}, {"page": { "url": "finxter.com", "access_time": "44"}}]
The JSON objects are sorted by value of the attribute 'access_time'
.
Solution: Use the key function to reduce each JSON object to a single value (access_time
). Then use this value as a basis for comparison when sorting the list. Here’s the code:
json = [{"page": {"url": "finxter.com", "access_time": "44"}}, {"page": {"url": "python.org", "access_time": "12"}}, {"page": {"url": "google.com", "access_time": "6"}}] json.sort(key=lambda x: int(x['page']['access_time'])) print(json) ''' [{"page": { "url": "google.com", "access_time": "6"}}, {"page": { "url": "python.org", "access_time": "12"}}, {"page": { "url": "finxter.com", "access_time": "44"}}] '''
You perform the following three steps:
- First, you obtain the inner dictionary with the call
x['page']
for each list elementx
. - Second, you obtain the string value of the attribute
'access_time'
. - Third, you convert the string to an integer. This integer is the basis for comparison and determines the order of the sorted list.
All three steps are necessary. Forget any of the three steps and it won’t work!
Python List Sort Key Examples
Let’s have a look at a series of examples to round up the discussion of the key function of Python’s list sort method.
lst = [(1, 2, 3), (0, 0, 7), (7, 0, 6)] lst.sort() print(lst) # [(0, 0, 7), (1, 2, 3), (7, 0, 6)] lst.sort(key=lambda x: x[2]) print(lst) # [(1, 2, 3), (7, 0, 6), (0, 0, 7)] lst.sort(key=lambda x: (x[1], x[2])) print(lst) # [(7, 0, 6), (0, 0, 7), (1, 2, 3)] lst.sort(key=lambda x: x[0] + x[1] + x[2]) print(lst) # [(1, 2, 3), (0, 0, 7), (7, 0, 6)] lst.sort(key=lambda x: max(x)) print(lst) # [(1, 2, 3), (0, 0, 7), (7, 0, 6)] lst.sort(key=max) print(lst) # [(1, 2, 3), (0, 0, 7), (7, 0, 6)]
Try these examples yourself in our interactive shell:
Where to Go From Here
The list.sort()
method sorts the list elements in place in an ascending manner. To customize the default sorting behavior, use the optional key
argument by passing a function that returns a comparable value for each element in the list. With the optional Boolean reverse
argument, you can switch from ascending (reverse=False
) to descending order (reverse=True
).
If you keep struggling with those basic Python commands and you feel stuck in your learning progress, I’ve got something for you: Python One-Liners (Amazon Link).
In the book, I’ll give you a thorough overview of critical computer science topics such as machine learning, regular expression, data science, NumPy, and Python basics—all in a single line of Python code!
OFFICIAL BOOK DESCRIPTION: Python One-Liners will show readers how to perform useful tasks with one line of Python code. Following a brief Python refresher, the book covers essential advanced topics like slicing, list comprehension, broadcasting, lambda functions, algorithms, regular expressions, neural networks, logistic regression and more. Each of the 50 book sections introduces a problem to solve, walks the reader through the skills necessary to solve that problem, then provides a concise one-liner Python solution with a detailed explanation.