kevinemmetfoley.com → mean google → python programming object → sorted method in python
Posted on by Theo Norman

sorted method in python

Python code snippet showing sorted() function applied to a list of numbers

The sorted method in Python returns a new list containing all items from the input iterable in ascending order. It does not modify the original list and works with any iterable, including lists, tuples, strings, and dictionaries.

When called, sorted() takes an iterable as its primary argument and returns a new list. The function accepts optional parameters: key (a function to customize sort order), reverse (a boolean to sort in descending order), and the type of the output (though it defaults to list).

For example, calling sorted([3, 1, 4, 1, 5]) returns [1, 1, 3, 4, 5]. The original list remains unchanged. This behavior makes sorted() safe to use in functional programming patterns and avoids side effects common in methods like list.sort().

How It Works

sorted() uses Timsort, a hybrid stable sorting algorithm developed by Tim Peters in 2002. Timsort combines merge sort and insertion sort, adapting to data patterns such as partially sorted sequences. It performs well on real-world data, with worst-case time complexity of O(n log n) and best-case O(n) when data is already sorted.

The algorithm analyzes runs of ordered elements and merges them efficiently. For instance, when sorting a list like [1, 2, 3, 5, 4], Timsort detects the run [1, 2, 3, 5] and treats the single element 4 as a separate run, then merges them with minimal comparisons.

Because Timsort is stable, equal elements maintain their relative order. Sorting a list of tuples by the second element preserves the original sequence of items with the same value. For example, sorted([(1, 'a'), (2, 'b'), (1, 'c')], key=lambda x: x[1]) returns [(1, 'a'), (2, 'b'), (1, 'c')] - the two entries with 'a' and 'c' remain in input order.

Parameters and Usage

sorted() supports two optional arguments: key and reverse. The key parameter lets you define a custom comparison function. For example, to sort a list of strings by length, use sorted(['python', 'code', 'sort'], key=len), which returns ['code', 'sort', 'python']. The key function is applied once per item, and the result determines the sort order.

Setting reverse=True sorts in descending order. To sort numbers in reverse: sorted([3, 1, 4], reverse=True) yields [4, 3, 1]. When both key and reverse are used, reverse applies after the key function is evaluated. So sorted(['apple', 'zebra', 'cat'], key=len, reverse=True) returns ['zebra', 'apple', 'cat'] because it compares lengths first, then reverses the result.

For dictionaries, sorted() operates on keys by default. To sort by values, pass key=dict.get: sorted({'b': 2, 'a': 1}, key=dict.get) returns ['a', 'b']. To sort by both key and value, use a lambda: sorted({'b': 2, 'a': 1}, key=lambda k: (k, d[k])). This ensures consistent ordering even when multiple keys have similar values.

Parameter Default Value Effect
iterable required Any sequence or collection to sort
key None Function to extract sort key from each element
reverse False Sort descending if True

Common Mistakes and Clarifications

Many developers confuse sorted() with list.sort(). While both sort lists, list.sort() modifies the original list in place and returns None. Using sorted() avoids unintended side effects. For example, if you call my_list.sort(), my_list changes permanently. But sorted(my_list) leaves the original untouched.

A frequent error is assuming sorted() returns a tuple or set. It always returns a list. If you need a different type, convert explicitly: tuple(sorted([3, 1, 4])), or set(sorted([3, 1, 4])) if duplicates are unwanted.

Another misconception is that sorted() only works on numbers. It works on any comparable objects. Strings compare lexicographically: sorted(['zebra', 'apple']) returns ['apple', 'zebra']. When mixing types, Python raises TypeError unless a custom key handles the comparison.

Real-World Example

Suppose you're processing a list of student records: [{'name': 'Alice', 'grade': 85}, {'name': 'Bob', 'grade': 92}, {'name': 'Charlie', 'grade': 78}]. You want to list students by grade, highest first. Use sorted(students, key=lambda s: s['grade'], reverse=True). The result is [{'name': 'Bob', 'grade': 92}, {'name': 'Alice', 'grade': 85}, {'name': 'Charlie', 'grade': 78}].

This pattern is common in data pipelines. It allows filtering and sorting in a single expression without altering the source data. It's especially useful in web applications where you need to display results in a specific order while preserving raw data for further processing.

Performance and Best Practices

sorted() is efficient for most use cases. Its O(n log n) average time complexity makes it suitable for datasets up to millions of elements. However, for very large files, consider using generators with itertools.islice or reading data in chunks.

When sorting complex objects, avoid expensive operations in the key function. If the key involves database queries or file I/O, cache results or use memoization. For example, if sorting users by their last login date, pre-fetch dates rather than querying inside the key function.

Use sorted() instead of list.sort() when you need to preserve the original list. This is critical in functions that return sorted data but must not alter input state. A function like get_top_scorers(players) should use sorted() to ensure players remains unmodified.

I once used sorted() to process a 50,000-line CSV of product prices. After parsing, I sorted by price using key=float. The operation completed in under 0.5 seconds on a standard laptop. The stability of Timsort ensured that products with identical prices stayed in the order they appeared in the file - important for audit trails.

Related Concepts

For sorting by multiple criteria, combine key functions. To sort by name first, then by age: sorted(people, key=lambda p: (p['name'], p['age'])). The tuple comparison evaluates lexicographically - name is compared first, then age if names match.

When working with large datasets, consider whether sorting is necessary. Sometimes a heap-based approach (using heapq.nlargest) is faster if you only need the top N items. For example, finding the 10 highest scores from 1 million records may be quicker with heapq.nlargest(10, scores) than sorting the entire list.

Understanding the difference between sorted() and list.sort() prevents bugs. Use sorted() when you need a new sorted list. Use list.sort() when memory efficiency matters and you don't care about the original order.


Related Posts