Python sorted() Function

Spread the love

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() or max(), 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.

Leave a Reply