Sort a list of dictionaries by value in Python
In Python, sorting a list of dictionaries by a specific key value is straightforward. Python offers two methods for achieving this: the sorted()
function and the sort()
method.
We will discuss the following topics in this blog post:
- Sort a list of dictionaries using
sorted()
function - Sort list of dictionaries using
sort()
method - Differences between
sorted()
function andsort()
method - Error handling
- Conclusion
# Sort a list of dictionaries using sorted() function
To sort a list of dictionaries using the sorted()
function, you can specify the key parameter to indicate which key’s value to use for sorting.
Here is an example:
my_list_of_dicts = [{'name': 'Alice', 'age': 30}, {
'name': 'Bob', 'age': 25}, {'name': 'Charlie', 'age': 35}]
sorted_list = sorted(my_list_of_dicts, key=lambda x: x['age'])
print(sorted_list)
# Output: [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]
In this example, the list of dictionaries is sorted based on the 'age'
key in ascending order.
(a) Sort a list of dictionaries in descending order
To sort a list of dictionaries in descending order, you can set the reverse
parameter of the sorted()
function to True
.
Here’s an example:
my_list_of_dicts = [{'name': 'Alice', 'age': 30}, {
'name': 'Bob', 'age': 25}, {'name': 'Charlie', 'age': 35}]
sorted_list = sorted(my_list_of_dicts, key=lambda x: x['age'], reverse=True)
print(sorted_list)
# Output: [{'name': 'Charlie', 'age': 35}, {'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}]
In this example, the list of dictionaries is sorted based on the value of 'age'
key in descending order. The reverse=True
parameter ensures that the sorting is done in reverse order.
(b) Sort a list of dictionaries based on a custom sorting function
You can also define your own custom sorting function to decide the sorting criteria and pass it as the key
parameter to the sorted()
function.
Here’s an example that sorts a list of dictionaries based on the length of the name
value:
# Define a custom function to determine the sorting key
def my_func(dict):
# Returns the length of the 'name' value in dictionary
return len(dict['name'])
my_list_of_dicts = [{'name': 'Alice', 'age': 30}, {
'name': 'Bob', 'age': 25}, {'name': 'Charlie', 'age': 35}]
# Sort the list of dictionaries using the custom function as the sorting key
sorted_list = sorted(my_list_of_dicts, key=my_func)
print(sorted_list)
# Output: [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]
(c) Sort a list of dictionaries based on multiple values
When working with data stored in dictionaries, you often need to sort them based on multiple criteria. For example, imagine you have a list of customer records with information like name, age, and city. You might want to sort them by age first, then by name within each age group.
To achieve this, you can pass a tuple of key functions to the key
parameter of the sorted()
function.
Here’s an example:
people_data = [
{"name": "Alice", "age": 30, "city": "New York"},
{"name": "Bob", "age": 25, "city": "Los Angeles"},
{"name": "Charlie", "age": 35, "city": "Chicago"},
{"name": "David", "age": 25, "city": "Detroit"}
]
sorted_data = sorted(people_data, key=lambda item: (item["age"], item["name"]))
print(sorted_data)
# Output: [{'name': 'Bob', 'age': 25, 'city': 'Los Angeles'}, {'name': 'David', 'age': 25, 'city': 'Detroit'}, {'name': 'Alice', 'age': 30, 'city': 'New York'}, {'name': 'Charlie', 'age': 35, 'city': 'Chicago'}]
In this example, the key
parameter of the sorted()
function is set to a lambda function. This lambda function takes each dictionary item
from people_data
and returns a tuple (item["age"], item["name"])
. This means the sorting is first done by age in ascending order and then by name in alphabetical order.
As you can see, the list is sorted first by age (Bob and David are both 25 years old), and then alphabetically by name within the same age group.
(d) Case-insensitive sorting list of dictionaries
Sorting a list of dictionaries based on string values requires special consideration, especially while doing case-insensitive sorting. Python provides built-in options to handle these scenarios.
Here’s an example:
fruits = [
{"name": "apple", "price": 20},
{"name": "Orange", "price": 50},
{"name": "Banana", "price": 10},
{"name": "grape", "price": 30}
]
# Sorting the list of dictionaries of fruits alphabetically by name (case-insensitive)
sorted_fruits = sorted(fruits, key=lambda fruit: (fruit["name"].casefold()))
print(sorted_fruits)
# Output: [{'name': 'apple', 'price': 20}, {'name': 'Banana', 'price': 10}, {'name': 'grape', 'price': 30}, {'name': 'Orange', 'price': 50}]
Using casefold()
ensures that the fruits
list is sorted alphabetically without considering the case. This Python string method converts all Unicode characters to lowercase, making it more comprehensive than lower()
for case-insensitive sorting.
(e) Sorting list of dictionaries using itemgetter()
The itemgetter()
is a function from the operator
module in Python that allows you to access specific elements within a sequence (like list, tuple, or dictionary) based on their index.
You can use this function to sort a list of dictionaries. Here’s an example:
from operator import itemgetter
fruits = [
{"name": "apple", "price": 20},
{"name": "orange", "price": 50},
{"name": "banana", "price": 10},
{"name": "grape", "price": 30}
]
# Sorting the list of dictionaries of fruits by price in ascending order
sorted_fruits = sorted(fruits, key=itemgetter("price"))
print(sorted_fruits)
# Output: [{'name': 'banana', 'price': 10}, {'name': 'apple', 'price': 20}, {'name': 'grape', 'price': 30}, {'name': 'orange', 'price': 50}]
In this example, itemgetter("price")
is used as the key function for sorting, which extracts the value associated with the key "price"
from each dictionary in the list for comparison during sorting.
(f) Lambda function vs itemgetter()
Lambda function:
- They are ideal for complex sorting criteria involving comparisons, calculations, or conditional logic.
- They are generally slower than
itemgetter()
for large datasets due to the overhead of function calls.
itemgetter()
:
- If your sorting logic is straightforward,
itemgetter()
is often more readable and efficient. - It is faster than the lambda function due to its optimized implementations.
In summary, lambda functions are convenient if your sorting criteria are complex or if you are working with small datasets. However, for larger datasets or when performance is a concern, itemgetter()
is generally preferred due to its efficiency.
# Sort list of dictionaries using sort() method
In Python, the sort()
method sorts the elements of the list in ascending order by default.
The basic syntax of the sort()
method is:
list_name.sort(key=None, reverse=False)
list_name
: The name of the list you want to sort.key
: (Optional) A function to execute to decide the order. Default is None.reverse
: (Optional) A boolean. If True the list is sorted in descending order. If False (default), the list is sorted in ascending order.
Alternatively, you can also use the sort()
method to sort a list of dictionaries.
Here’s an example:
my_list_of_dicts = [{'name': 'Alice', 'age': 30}, {
'name': 'Bob', 'age': 25}, {'name': 'Charlie', 'age': 35}]
my_list_of_dicts.sort(key=lambda x: x['age'])
print(my_list_of_dicts)
# Output: [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]
You can replace sorted()
function with the sort()
method for all the examples we talked about earlier in this guide.
# Differences between sorted() function and sort() method
The sorted()
function and sort()
method are both used for sorting elements in a Python list, but they have some key differences:
- Return type:
sorted()
: Returns a new sorted list from the elements of the iterable (list, tuple, or string). The original iterable remains unchanged.sort()
: Sorts the elements of the list in-place and returns None. The original list is modified.
- Mutability:
sorted()
: Creates a new sorted list without modifying the original iterable.sort()
: Modifies the original list in-place.
- Usage:
sorted()
: It can be used with any iterable (list, tuple, or string), not just lists. It returns a new sorted list regardless of the type of the original iterable.sort()
: Applies only to lists. It is a method of the list class and can only be used with lists.
- Performance:
- The
sort()
method is generally faster than thesorted()
function because it modifies the list in-place, avoiding the overhead of creating a new list.
- The
Here’s a table summarizing the key differences:
Feature | sorted() | sort() |
---|---|---|
Return Value | New sorted list | None |
Mutability | Non-mutating | Mutates original list |
Usage | Any iterable object | Lists only |
Performance | Generally slower | Generally faster |
# Error handling
Error handling is an essential aspect of any code, especially when dealing with sorting operations on data structures like lists of dictionaries. Let’s discuss some common error scenarios and how to handle them gracefully:
(a) Missing key
If you try to sort by a key that doesn’t exist in all dictionaries, you will get a KeyError
.
To handle this, you can either ensure that all dictionaries have the required key, or use try-except
blocks to catch and handle the KeyError
.
For example:
my_list_of_dicts = [{'name': 'Alice', 'age': 30}, {
'name': 'Bob', 'age': 25}, {'name': 'Charlie'}]
try:
sorted_list = sorted(my_list_of_dicts, key=lambda x: x['age'])
print(sorted_list)
except KeyError:
print("One or more dictionaries do not contain the specified key for sorting")
# Output: One or more dictionaries do not contain the specified key for sorting
In this example, the sorted()
function attempts to access the 'age'
key of one of the dictionaries in the list, it encounters a KeyError
because one of the dictionaries does not contain the ‘age’ key. Therefore, the code jumps to the except
block and prints the message indicating that one or more dictionaries do not contain the specified key for sorting.
If you want to sort a list of dictionaries regardless of whether the key is missing, you can use the .get(key, default_value)
to provide a default value.
Here’s an example:
my_list_of_dicts = [{'name': 'Alice', 'age': 30}, {
'name': 'Bob', 'age': 25}, {'name': 'Charlie'}]
try:
sorted_list = sorted(my_list_of_dicts, key=lambda x: x.get('age', 100))
print(sorted_list)
except KeyError:
print("One or more dictionaries do not contain the specified key for sorting")
# Output: [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie'}]
In this example, the get()
method to used to retrieve the value of a key from the dictionary. It takes two arguments: the key whose value you want to retrieve and the optional default value.
Here’s how it works:
- If the key exists in the dictionary,
x.get('age', 100)
, returns the corresponding value associated with that key. - If the key doesn’t exist in the dictionary,
x.get('age', 100)
returns the default value provided as the second argument, which in this case is100
.
You can use infinity inf
to treat missing key values as greater than other values, and similarly, you can use -inf
to treat them as smaller.
Here’s an example:
my_list_of_dicts = [{'name': 'Alice', 'age': 30}, {
'name': 'Bob', 'age': 25}, {'name': 'Charlie'}]
print(sorted(my_list_of_dicts, key=lambda x: x.get('age', float('inf'))))
# Output: [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie'}]
print(sorted(my_list_of_dicts, key=lambda x: x.get('age', -float('inf'))))
# Output: [{'name': 'Charlie'}, {'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}]
(b) Uncomparable Types
If you try to compare values of different data types (e.g. string vs. integer), you will get a TypeError
.
Check the data types before sorting and convert them if necessary, or raise a specific error message to guide the user.
Here’s an example:
my_list_of_dicts = [{'name': 'Alice', 'age': 40}, {'name': 'Bob', 'age': 25}, {
'name': 'Charlie', 'age': 'thirty'}]
try:
sorted_list = sorted(my_list_of_dicts, key=lambda x: x['age'])
print(sorted_list)
except TypeError:
print("One or more dictionaries contain inappropriate data for sorting")
In this example, the sorted()
function attempts to compare the 'age'
values of the dictionaries in the list, it encounters a TypeError
due to the fact that one of the dictionaries has a string value ('thirty'
) for the 'age'
key, which cannot be compared with integers. Therefore, the code jumps to the except
block and prints the message indicating that inappropriate data for sorting was found.
Conclusion
In this guide, we discussed how to sort a list of dictionaries using the sorted()
and sort()
methods in Python. We covered various techniques and scenarios, including custom sorting functions, sorting based on multiple values, and error handling strategies for common issues encountered during sorting operations on lists of dictionaries.
Here’s a summary of when to use each:
Use sorted()
:
- If you want to keep the original list intact.
- If you need to create a new sorted list from any iterable object.
Use sort()
:
- If you want to modify the original list and don’t need to keep the original order.
- If performance is a major concern.
Use lambda function:
- If your sorting criteria are complex or if you are working with small datasets.
Use itemgetter()
:
- For large datasets or when performance is a concern.
By understanding these techniques, you can effectively manipulate and sort data stored in dictionaries to meet the requirements of your Python programs.
Happy coding → 3000