Sort a list of objects by multiple attributes in Python
This post will discuss how to sort a list of objects by multiple attributes in Python.
In the previous post, we have seen how to sort a list of objects using a single attribute. This post will discuss how to sort a list of objects using multiple attributes in Python.
1. Using list.sort() function
A Pythonic solution to in-place sort a list of objects using multiple attributes is to use the list.sort() function. It accepts two optional keyword-only arguments: key and reverse and produces a stable sort. The key specifies a function of one argument to extract a comparison key from each list item, and the list will be sorted in reversed order when the reverse is True.
To illustrate, the following sorts a list of Employee object with some attributes sorted in the natural order, and remaining attributes sorted in the reverse order.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
class Associate: def __init__(self, name, dept, salary): self.name = name self.dept = dept self.salary = salary def __repr__(self): return '{' + self.name + ', ' + self.dept + ', ' + str(self.salary) + '}' if __name__ == '__main__': associates = [ Associate('James', 'Finance', 80000), Associate('Robert', 'Construction', 60000), Associate('James', 'Telecom', 70000) ] # 1. Sort by only `dept` attribute associates.sort(key=lambda x: x.dept) # [{Robert, Construction, 60000}, {James, Finance, 80000}, {James, Telecom, 70000}] print(associates) # 2. Sort by `name` attribute, followed by `dept` attribute associates.sort(key=lambda x: (x.name, x.dept)) # [{James, Finance, 80000}, {James, Telecom, 70000}, {Robert, Construction, 60000}] print(associates) # 3. Sort by `name` attribute in reverse order, #, followed by `dept` attribute in reverse order associates.sort(key=lambda x: (x.name, x.dept), reverse=True) # [{Robert, Construction, 60000}, {James, Telecom, 70000}, {James, Finance, 80000}] print(associates) # 4. Sort by `name` attribute in the natural order, #, followed by numeric `salary` attribute in reverse order associates.sort(key=lambda x: (x.name, -x.salary)) # [{James, Finance, 80000}, {James, Telecom, 70000}, {Robert, Construction, 60000}] print(associates) |
If you don’t need any attributes sorted in reverse order, consider using the attrgetter() function from the operator module to produce the key.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
from operator import attrgetter class Associate: def __init__(self, name, dept): self.name = name self.dept = dept def __repr__(self): return '{' + self.name + ', ' + self.dept + '}' if __name__ == '__main__': associates = [ Associate('James', 'Telecom'), Associate('Robert', 'Construction'), Associate('James', 'Finance') ] # sort by `name` and `dept` attribute associates.sort(key=attrgetter('name', 'dept')) # [{James, Finance}, {James, Telecom}, {Robert, Construction}] print(associates) |
2. Using sorted() function
The list.sort() function modifies the list in-place. To return a new sorted list instance, you can use the sorted() built-in. It accepts the same keyword-only arguments as the list.sort() function.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class Associate: def __init__(self, name, dept): self.name = name self.dept = dept def __repr__(self): return '{' + self.name + ', ' + self.dept + '}' if __name__ == '__main__': associates = [ Associate('James', 'Telecom'), Associate('Robert', 'Construction'), Associate('James', 'Finance') ] # sort by `name` and `dept` attribute sortByNameAndDept = sorted(associates, key=lambda x: (x.name, x.dept)) # [{James, Finance}, {James, Telecom}, {Robert, Construction}] print(sortByNameAndDept) |
That’s all about sorting a list of objects by multiple attributes in Python.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)