The sorted( ) function sorts the elements of a given iterable in ascending or descending order and returns it as a list.
Syntax:
The sorted()
function has the following syntax:
sorted(iterable, key=None, reverse=False)
Parameters:
sorted( ) function can take three parameters.
- iterable: The sequence of items (list, tuple, string, etc.) or collection (set, dictionary, etc.) to sort.
- key (optional): A function that serves as a key for the sort comparison. This parameter is not to modify the objects you’re sorting; instead, it specifies a method to extract a comparison key from each list element.
- reverse (optional): A boolean value. If set to
True
, the sorted list is reversed (or sorted in descending order).
Return Value:
The sorted()
function returns a new sorted list from the items in the iterable.
How sorted() Work in Python?
To understand how sorted()
works, let’s look at a simple example:
Sorting a Python list using sorted()
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
sorted_numbers = sorted(numbers)
print(sorted_numbers) # Output: [1, 1, 2, 3, 4, 5, 6, 9]
In the example above, sorted()
takes the list numbers
and returns a new list with the elements sorted in ascending order.
Custom Sorting With key Parameter
The real power of sorted()
lies in its key
parameter, which allows for custom sorting. The key
parameter accepts a function to be called on each list element prior to making comparisons.
Sorting by Length of Items
For instance, to sort a list of strings by their length:
words = ["banana", "pie", "Washington", "book"]
sorted_words = sorted(words, key=len)
print(sorted_words) # Output: ['pie', 'book', 'banana', 'Washington']
Sorting by a Custom Function
You can also define your own function:
def get_second_element(item):
return item[1]
pairs = [(1, 3), (3, 2), (2, 1)]
sorted_pairs = sorted(pairs, key=get_second_element)
print(sorted_pairs) # Output: [(2, 1), (3, 2), (1, 3)]
Using a Lambda Function
For convenience, a lambda function is often used with sorted()
:
pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
sorted_by_second = sorted(pairs, key=lambda pair: pair[1])
print(sorted_by_second) # Output: [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
Sorting in Reverse
By setting the reverse
parameter to True
, you can sort the items in descending order:
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
sorted_numbers_desc = sorted(numbers, reverse=True)
print(sorted_numbers_desc) # Output: [9, 6, 5, 4, 3, 2, 1, 1]
Sorting Without Changing the Original Iterable
One of the advantages of using sorted()
is that it creates a new list and does not change the original iterable. This is particularly useful when the original order needs to be preserved for later use.
Complex Sorts: Sorting by Multiple Keys
Sorting by multiple keys involves ordering a collection of items based on more than one criterion. In Python, when you pass a function to the key
argument in sorted()
, that function is used to generate a sorting key for each element in the iterable. When you want to sort by multiple keys, you can have the function return a tuple that represents the priority of each sort key.
Let’s work through an example where we have a list of records for students. Each record contains the student’s name, grade, and age. Our goal is to sort the list first by grade in descending order, then by age in ascending order, and finally by name in ascending order.
Here is how we might do this:
students = [
('John', 'Grade 4', 12),
('Anna', 'Grade 3', 9),
('Barry', 'Grade 4', 10),
('Daisy', 'Grade 3', 11),
('Cindy', 'Grade 4', 10),
('Charlie', 'Grade 3', 9),
('Fred', 'Grade 4', 12)
]
# Our key function will return a tuple where we first take the grade and multiply by -1
# because we want to sort grades in descending order.
# Then we take the age for ascending order,
# and finally the name for alphabetical order.
def sort_key(record):
grade = int(record[1].split(' ')[1]) # Extract the grade number (int) from the string.
age = record[2]
name = record[0]
return (-grade, age, name)
sorted_students = sorted(students, key=sort_key)
for student in sorted_students:
print(student)
Output:
('Barry', 'Grade 4', 10)
('Cindy', 'Grade 4', 10)
('Fred', 'Grade 4', 12)
('John', 'Grade 4', 12)
('Anna', 'Grade 3', 9)
('Charlie', 'Grade 3', 9)
('Daisy', 'Grade 3', 11)
sorted() with Custom Objects
You can even sort a list of custom objects by defining a __lt__
method that sorted()
will use or by providing a key
function that returns a property to sort by.
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f'{self.name} ({self.age})'
people = [Person('Alice', 30), Person('Bob', 25), Person('Charlie', 35)]
sorted_people = sorted(people, key=lambda p: p.age)
print(sorted_people) # Output: [Bob (25), Alice (30), Charlie (35)]
Performance Considerations
The sorted()
function is implemented using the Timsort algorithm, which is very efficient for real-world data. It has O(n log n) time complexity on average. However, when sorting large datasets, it’s important to consider the complexity of the key
function.
When Not to Use sorted()
- When you only need the minimum or maximum element, consider using
min()
ormax()
, which are more efficient. - If you’re repeatedly sorting the same list, it may be more efficient to sort it once with
list.sort()
and then use the list as needed.
Conclusion
The sorted()
function is a powerful and versatile tool in Python that simplifies the task of sorting various types of data. By understanding and utilizing its key
and reverse
parameters effectively, developers can perform complex sorts succinctly and efficiently. Its non-destructive nature preserves original data, allowing for greater flexibility in data manipulation. Whether working with simple lists or complex objects, sorted()
provides a robust solution for organizing data in Python.