Python List Sorting: Complete Guide to sort() and sorted()

Master Python list sorting with built-in methods. Learn sort() vs sorted(), custom key functions, performance tips, and advanced techniques.

Sorting Lists in Python

Table of Contents

1. [Introduction](#introduction) 2. [Built-in Sorting Methods](#built-in-sorting-methods) 3. [The sort() Method](#the-sort-method) 4. [The sorted() Function](#the-sorted-function) 5. [Sorting Different Data Types](#sorting-different-data-types) 6. [Custom Sorting with Key Functions](#custom-sorting-with-key-functions) 7. [Reverse Sorting](#reverse-sorting) 8. [Advanced Sorting Techniques](#advanced-sorting-techniques) 9. [Performance Considerations](#performance-considerations) 10. [Common Use Cases and Examples](#common-use-cases-and-examples) 11. [Best Practices](#best-practices)

Introduction

Sorting is one of the most fundamental operations in computer programming and data manipulation. Python provides powerful and flexible built-in methods for sorting lists that are both efficient and easy to use. Understanding how to properly sort lists is essential for data processing, algorithm implementation, and general programming tasks.

Python uses a stable sorting algorithm called Timsort, which is a hybrid stable sorting algorithm derived from merge sort and insertion sort. This algorithm provides excellent performance characteristics with O(n log n) worst-case time complexity and O(n) best-case time complexity for already sorted data.

Built-in Sorting Methods

Python offers two primary ways to sort lists:

| Method | Type | Modifies Original | Returns | Use Case | |--------|------|-------------------|---------|----------| | list.sort() | Method | Yes | None | When you want to sort in-place | | sorted() | Function | No | New list | When you want to keep original unchanged |

Key Differences Summary

The fundamental difference between these two approaches lies in whether they modify the original list or create a new one. The sort() method is more memory-efficient as it sorts the list in-place, while sorted() creates a new list, preserving the original.

The sort() Method

The sort() method is a list method that sorts the list in-place, meaning it modifies the original list directly and returns None.

Syntax

`python list.sort(key=None, reverse=False) `

Parameters

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | key | function | None | Function to extract comparison key from each element | | reverse | boolean | False | If True, sorts in descending order |

Basic Examples

`python

Basic sorting of integers

numbers = [64, 34, 25, 12, 22, 11, 90] print("Original list:", numbers) numbers.sort() print("Sorted list:", numbers)

Output: [11, 12, 22, 25, 34, 64, 90]

Basic sorting of strings

fruits = ["banana", "apple", "cherry", "date"] print("Original fruits:", fruits) fruits.sort() print("Sorted fruits:", fruits)

Output: ['apple', 'banana', 'cherry', 'date']

Sorting floating-point numbers

prices = [19.99, 5.50, 12.25, 3.75, 25.00] prices.sort() print("Sorted prices:", prices)

Output: [3.75, 5.5, 12.25, 19.99, 25.0]

`

Important Notes about sort()

1. Returns None: The sort() method always returns None, not the sorted list 2. In-place operation: Modifies the original list directly 3. Memory efficient: Does not create a new list 4. Cannot chain operations: Since it returns None, you cannot chain other operations

`python

Common mistake - trying to assign the result of sort()

numbers = [3, 1, 4, 1, 5] sorted_numbers = numbers.sort() # This assigns None to sorted_numbers print(sorted_numbers) # Output: None

Correct approach

numbers = [3, 1, 4, 1, 5] numbers.sort() # Sort in-place print(numbers) # Output: [1, 1, 3, 4, 5] `

The sorted() Function

The sorted() function creates a new sorted list from any iterable, leaving the original unchanged.

Syntax

`python sorted(iterable, key=None, reverse=False) `

Parameters

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | iterable | iterable | Required | Any iterable object (list, tuple, string, etc.) | | key | function | None | Function to extract comparison key from each element | | reverse | boolean | False | If True, sorts in descending order |

Basic Examples

`python

Sorting a list without modifying the original

original_numbers = [64, 34, 25, 12, 22, 11, 90] sorted_numbers = sorted(original_numbers) print("Original:", original_numbers) # [64, 34, 25, 12, 22, 11, 90] print("Sorted:", sorted_numbers) # [11, 12, 22, 25, 34, 64, 90]

Sorting different iterables

sorted_string = sorted("python") print(sorted_string) # ['h', 'n', 'o', 'p', 't', 'y']

sorted_tuple = sorted((5, 2, 8, 1, 9)) print(sorted_tuple) # [1, 2, 5, 8, 9]

Sorting with assignment and chaining

numbers = [3, 1, 4, 1, 5, 9, 2, 6] result = sorted(numbers)[:3] # Get first 3 elements of sorted list print(result) # [1, 1, 2] `

Sorting Different Data Types

Numeric Data Types

`python

Integers

integers = [5, 2, 8, 1, 9, 3] integers.sort() print("Sorted integers:", integers) # [1, 2, 3, 5, 8, 9]

Floating-point numbers

floats = [3.14, 2.71, 1.41, 0.57, 2.23] floats.sort() print("Sorted floats:", floats) # [0.57, 1.41, 2.23, 2.71, 3.14]

Mixed numeric types (integers and floats)

mixed_numbers = [3, 1.5, 2, 4.7, 1] mixed_numbers.sort() print("Sorted mixed:", mixed_numbers) # [1, 1.5, 2, 3, 4.7] `

String Data Types

`python

Simple strings

words = ["zebra", "apple", "banana", "cherry"] words.sort() print("Sorted words:", words) # ['apple', 'banana', 'cherry', 'zebra']

Case-sensitive sorting (uppercase comes before lowercase)

mixed_case = ["apple", "Banana", "cherry", "Date"] mixed_case.sort() print("Case-sensitive:", mixed_case) # ['Banana', 'Date', 'apple', 'cherry']

Case-insensitive sorting using key parameter

mixed_case = ["apple", "Banana", "cherry", "Date"] mixed_case.sort(key=str.lower) print("Case-insensitive:", mixed_case) # ['apple', 'Banana', 'cherry', 'Date'] `

Boolean Data Types

`python

Boolean values (False < True)

booleans = [True, False, True, False, True] booleans.sort() print("Sorted booleans:", booleans) # [False, False, False, True, True] `

Custom Sorting with Key Functions

The key parameter allows you to specify a function that extracts a comparison key from each element. This is one of the most powerful features of Python's sorting functionality.

Built-in Key Functions

`python

Sorting by absolute value

numbers = [-5, 2, -8, 1, 9, -3] numbers.sort(key=abs) print("Sorted by absolute value:", numbers) # [1, 2, -3, -5, 8, 9]

Sorting strings by length

words = ["python", "java", "c", "javascript", "go"] words.sort(key=len) print("Sorted by length:", words) # ['c', 'go', 'java', 'python', 'javascript']

Case-insensitive string sorting

words = ["Apple", "banana", "Cherry", "date"] words.sort(key=str.lower) print("Case-insensitive:", words) # ['Apple', 'banana', 'Cherry', 'date'] `

Lambda Functions as Keys

`python

Sorting tuples by second element

students = [("Alice", 85), ("Bob", 90), ("Charlie", 78), ("Diana", 92)] students.sort(key=lambda x: x[1]) print("Sorted by grade:", students)

[('Charlie', 78), ('Alice', 85), ('Bob', 90), ('Diana', 92)]

Sorting by multiple criteria using tuples

students = [("Alice", 85, 20), ("Bob", 90, 19), ("Charlie", 85, 21)] students.sort(key=lambda x: (x[1], x[2])) # Sort by grade, then by age print("Sorted by grade then age:", students)

[('Alice', 85, 20), ('Charlie', 85, 21), ('Bob', 90, 19)]

Sorting strings by last character

words = ["hello", "world", "python", "code"] words.sort(key=lambda x: x[-1]) print("Sorted by last character:", words) # ['code', 'hello', 'world', 'python'] `

Custom Key Functions

`python def get_second_word(sentence): """Extract the second word from a sentence for sorting.""" words = sentence.split() return words[1] if len(words) > 1 else ""

sentences = [ "The quick brown", "A slow turtle", "The fast car", "A big elephant" ]

sentences.sort(key=get_second_word) print("Sorted by second word:", sentences)

['A big elephant', 'The fast car', 'The quick brown', 'A slow turtle']

Sorting by word count

def word_count(sentence): return len(sentence.split())

sentences = ["Hello world", "Python is great", "Sort", "This is a test"] sentences.sort(key=word_count) print("Sorted by word count:", sentences)

['Sort', 'Hello world', 'Python is great', 'This is a test']

`

Reverse Sorting

Both sort() and sorted() support reverse sorting through the reverse parameter.

Using the reverse Parameter

`python

Reverse sorting with sort()

numbers = [64, 34, 25, 12, 22, 11, 90] numbers.sort(reverse=True) print("Descending order:", numbers) # [90, 64, 34, 25, 22, 12, 11]

Reverse sorting with sorted()

words = ["apple", "banana", "cherry", "date"] reverse_sorted = sorted(words, reverse=True) print("Reverse alphabetical:", reverse_sorted) # ['date', 'cherry', 'banana', 'apple']

Reverse sorting with key function

students = [("Alice", 85), ("Bob", 90), ("Charlie", 78)] students.sort(key=lambda x: x[1], reverse=True) print("Highest grades first:", students)

[('Bob', 90), ('Alice', 85), ('Charlie', 78)]

`

Alternative Reverse Methods

`python

Using reversed() function (creates iterator)

numbers = [1, 2, 3, 4, 5] numbers.sort() reversed_numbers = list(reversed(numbers)) print("Reversed after sorting:", reversed_numbers) # [5, 4, 3, 2, 1]

Slicing with negative step

numbers = [64, 34, 25, 12, 22, 11, 90] sorted_desc = sorted(numbers)[::-1] print("Descending via slicing:", sorted_desc) # [90, 64, 34, 25, 22, 12, 11] `

Advanced Sorting Techniques

Multi-level Sorting

`python

Sorting by multiple criteria

employees = [ ("John", "Engineering", 75000), ("Alice", "Marketing", 65000), ("Bob", "Engineering", 80000), ("Carol", "Marketing", 70000), ("Dave", "Engineering", 75000) ]

Sort by department, then by salary (descending)

employees.sort(key=lambda x: (x[1], -x[2])) print("Sorted by dept, then salary desc:") for emp in employees: print(emp)

('Bob', 'Engineering', 80000)

('Dave', 'Engineering', 75000)

('John', 'Engineering', 75000)

('Carol', 'Marketing', 70000)

('Alice', 'Marketing', 65000)

`

Sorting with operator Module

`python from operator import itemgetter, attrgetter

Using itemgetter for tuple/list sorting

students = [("Alice", 85), ("Bob", 90), ("Charlie", 78)] students.sort(key=itemgetter(1)) # Sort by second element print("Using itemgetter:", students)

Multiple key sorting with itemgetter

data = [("John", 25, 50000), ("Alice", 30, 60000), ("Bob", 25, 55000)] data.sort(key=itemgetter(1, 2)) # Sort by age, then salary print("Multi-key sorting:", data)

Using attrgetter for object sorting

class Person: def __init__(self, name, age): self.name = name self.age = age def __repr__(self): return f"Person('{self.name}', {self.age})"

people = [Person("Alice", 30), Person("Bob", 25), Person("Charlie", 35)] people.sort(key=attrgetter('age')) print("Sorted by age:", people) `

Stable Sorting

Python's sort is stable, meaning equal elements maintain their relative order.

`python

Demonstrating stable sorting

students = [ ("Alice", "A"), ("Bob", "B"), ("Charlie", "A"), ("Diana", "B"), ("Eve", "A") ]

print("Original order:", students) students.sort(key=lambda x: x[1]) # Sort by grade print("After sorting by grade (stable):", students)

Students with same grade maintain their original relative order

`

Performance Considerations

Time Complexity Comparison

| Operation | Average Case | Worst Case | Best Case | |-----------|--------------|------------|-----------| | list.sort() | O(n log n) | O(n log n) | O(n) | | sorted() | O(n log n) | O(n log n) | O(n) |

Memory Usage Comparison

| Method | Memory Usage | Explanation | |--------|--------------|-------------| | list.sort() | O(1) extra space | Sorts in-place | | sorted() | O(n) extra space | Creates new list |

Performance Testing Example

`python import time import random

def performance_test(): # Generate test data size = 100000 test_data = [random.randint(1, 1000) for _ in range(size)] # Test sort() method data_copy1 = test_data.copy() start_time = time.time() data_copy1.sort() sort_time = time.time() - start_time # Test sorted() function data_copy2 = test_data.copy() start_time = time.time() sorted_data = sorted(data_copy2) sorted_time = time.time() - start_time print(f"sort() method time: {sort_time:.4f} seconds") print(f"sorted() function time: {sorted_time:.4f} seconds")

Uncomment to run performance test

performance_test()

`

Common Use Cases and Examples

Data Processing

`python

Processing sales data

sales_data = [ {"product": "Laptop", "price": 999.99, "quantity": 5}, {"product": "Mouse", "price": 29.99, "quantity": 50}, {"product": "Keyboard", "price": 79.99, "quantity": 20}, {"product": "Monitor", "price": 299.99, "quantity": 8} ]

Sort by total revenue (price * quantity)

sales_data.sort(key=lambda x: x["price"] * x["quantity"], reverse=True) print("Products sorted by revenue:") for item in sales_data: revenue = item["price"] * item["quantity"] print(f"{item['product']}: ${revenue:.2f}") `

Text Processing

`python

Sorting words by various criteria

text = "The quick brown fox jumps over the lazy dog" words = text.lower().split()

Remove duplicates and sort

unique_words = sorted(set(words)) print("Unique words alphabetically:", unique_words)

Sort by word length, then alphabetically

words_by_length = sorted(set(words), key=lambda x: (len(x), x)) print("Words by length then alphabetically:", words_by_length)

Sort by frequency (most common first)

from collections import Counter word_freq = Counter(words) words_by_frequency = sorted(word_freq.items(), key=lambda x: x[1], reverse=True) print("Words by frequency:", words_by_frequency) `

File and Path Sorting

`python import os from pathlib import Path

Sorting file paths

file_paths = [ "/home/user/document.txt", "/home/user/image.jpg", "/home/user/data.csv", "/home/user/script.py" ]

Sort by file extension

file_paths.sort(key=lambda x: Path(x).suffix) print("Sorted by extension:", file_paths)

Sort by filename (without path)

file_paths.sort(key=lambda x: Path(x).name) print("Sorted by filename:", file_paths) `

Numerical Analysis

`python

Sorting coordinates by distance from origin

import math

coordinates = [(3, 4), (1, 1), (5, 12), (0, 0), (8, 6)]

def distance_from_origin(point): x, y = point return math.sqrt(x2 + y2)

coordinates.sort(key=distance_from_origin) print("Points sorted by distance from origin:") for point in coordinates: dist = distance_from_origin(point) print(f"{point}: {dist:.2f}") `

Best Practices

When to Use sort() vs sorted()

| Use list.sort() when: | Use sorted() when: | |-------------------------|----------------------| | You want to modify the original list | You need to keep the original list unchanged | | Memory efficiency is important | You're working with immutable data types | | You don't need the original data | You want to chain operations | | Working with very large lists | Creating a new sorted version |

Code Examples of Best Practices

`python

Best Practice 1: Use appropriate method based on need

def process_grades(student_grades): # Use sorted() when you need both original and sorted data original_grades = [85, 92, 78, 96, 88] sorted_grades = sorted(original_grades) print(f"Original order: {original_grades}") print(f"Sorted order: {sorted_grades}") # Use sort() when you only need the sorted version final_grades = [85, 92, 78, 96, 88] final_grades.sort() return final_grades

Best Practice 2: Use key functions effectively

def sort_students_efficiently(students): # Good: Use key function instead of custom comparison students.sort(key=lambda student: student.gpa, reverse=True) # Avoid: Don't use multiple sorts when one key function can handle it # students.sort(key=lambda s: s.name) # Don't do this # students.sort(key=lambda s: s.gpa, reverse=True) # followed by this # Better: Use tuple for multiple criteria students.sort(key=lambda s: (-s.gpa, s.name)) # GPA desc, then name asc

Best Practice 3: Handle edge cases

def safe_sort(data, key_func=None): """Safely sort data with error handling.""" if not data: return [] try: if key_func: return sorted(data, key=key_func) else: return sorted(data) except TypeError as e: print(f"Cannot sort mixed types: {e}") return data

Best Practice 4: Use appropriate data structures

def efficient_top_n(data, n): """Get top N elements efficiently.""" import heapq # For small N relative to data size, use heapq if n < len(data) / 10: return heapq.nlargest(n, data) else: # For large N, regular sorting is more efficient return sorted(data, reverse=True)[:n] `

Common Pitfalls and How to Avoid Them

`python

Pitfall 1: Trying to assign result of sort()

Wrong:

numbers = [3, 1, 4, 1, 5] sorted_numbers = numbers.sort() # This is None!

Correct:

numbers = [3, 1, 4, 1, 5] numbers.sort() # Modify in-place

OR

sorted_numbers = sorted(numbers) # Create new list

Pitfall 2: Sorting mixed types (Python 3)

This will raise TypeError in Python 3:

mixed = [1, "hello", 3.14]

mixed.sort()

Solution: Use key function to convert to comparable type

mixed = [1, "hello", 3.14] mixed.sort(key=str) # Convert all to strings for comparison

Pitfall 3: Modifying list while iterating

numbers = [1, 3, 2, 5, 4]

Wrong: Don't modify the list you're iterating over

for i, num in enumerate(numbers):

if num % 2 == 0:

numbers.sort() # This can cause issues

Correct: Work with a copy or create new list

numbers = [1, 3, 2, 5, 4] for num in numbers.copy(): # Iterate over copy if num % 2 == 0: numbers.sort() break `

Performance Optimization Tips

`python

Tip 1: Pre-compute expensive key calculations

def expensive_key_function(item): # Simulate expensive computation return sum(ord(c) for c in str(item)) 2

Instead of calling expensive function for each comparison:

data = ["apple", "banana", "cherry", "date"]

data.sort(key=expensive_key_function) # Inefficient for multiple comparisons

Better: Use decorate-sort-undecorate pattern (built into Python's sort)

Python automatically caches key function results

data.sort(key=expensive_key_function) # Python optimizes this

Tip 2: Use operator functions for simple operations

from operator import itemgetter, attrgetter

Instead of lambda functions for simple operations:

students = [("Alice", 85), ("Bob", 90), ("Charlie", 78)]

students.sort(key=lambda x: x[1]) # Works but less efficient

Better:

students.sort(key=itemgetter(1)) # More efficient

Tip 3: Consider locale-specific sorting for text

import locale

def locale_aware_sort(text_list): """Sort text considering locale-specific rules.""" try: locale.setlocale(locale.LC_ALL, '') # Use system locale return sorted(text_list, key=locale.strxfrm) except locale.Error: # Fallback to regular sorting return sorted(text_list) `

This comprehensive guide covers all essential aspects of sorting lists in Python, from basic usage to advanced techniques and best practices. The examples provided demonstrate real-world applications and help you understand when and how to use different sorting approaches effectively.

Tags

  • Lists
  • algorithms
  • data-structures
  • sorting

Related Articles

Related Books - Expand Your Knowledge

Explore these Python books to deepen your understanding:

Browse all IT books

Popular Technical Articles & Tutorials

Explore our comprehensive collection of technical articles, programming tutorials, and IT guides written by industry experts:

Browse all 8+ technical articles | Read our IT blog

Python List Sorting: Complete Guide to sort() and sorted()