How to sort a list in Python

Python's list sorting capabilities empower developers to organize data efficiently. The language provides built-in methods like sort() and sorted() that handle both simple lists and complex data structures with remarkable flexibility.

This guide covers essential sorting techniques, optimization tips, and practical examples—all created with Claude, an AI assistant built by Anthropic. You'll learn proven strategies for implementing robust sorting solutions.

Basic list sorting with sort() method

numbers = [5, 2, 8, 1, 9]
numbers.sort()
print(numbers)
[1, 2, 5, 8, 9]

The sort() method modifies lists in-place, permanently reordering the original elements in ascending order. This approach consumes less memory than creating a new sorted list, making it ideal for large datasets where performance matters.

Python's sorting algorithm uses Timsort—a hybrid sorting algorithm that combines the best features of merge sort and insertion sort. The method automatically handles different data types intelligently:

  • Numbers sort numerically (1 comes before 2)
  • Strings sort alphabetically (a comes before b)
  • Mixed-type comparisons follow Python's default ordering rules

Common sorting techniques

Building on Python's sort() method, three additional techniques unlock even more powerful ways to organize your data with precision and flexibility.

Sorting with the sorted() function

original = [5, 2, 8, 1, 9]
sorted_list = sorted(original)
print("Original:", original)
print("Sorted:", sorted_list)
Original: [5, 2, 8, 1, 9]
Sorted: [1, 2, 5, 8, 9]

Unlike sort(), the sorted() function creates a new list containing the sorted elements while preserving the original list unchanged. This non-destructive approach gives you more flexibility when you need to maintain both sorted and unsorted versions of your data.

  • The function returns a fresh list with elements arranged in ascending order
  • Your original list remains exactly as it was before sorting
  • You can assign the sorted result to any variable name you choose

This approach requires slightly more memory since it creates a new list. However, it offers a cleaner solution when you need to preserve the original data order while working with a sorted version.

Sorting in reverse order

numbers = [5, 2, 8, 1, 9]
numbers.sort(reverse=True)
print(numbers)
[9, 8, 5, 2, 1]

The reverse=True parameter flips Python's default ascending sort order, arranging elements from highest to lowest. This straightforward approach works with both the sort() method and sorted() function.

  • Numbers arrange from largest to smallest (9 down to 1)
  • Strings order from Z to A
  • The operation modifies the list directly, just like regular sorting

You'll often need descending order when building leaderboards, displaying recent items first, or prioritizing tasks. The reverse parameter offers a cleaner solution than sorting normally and then reversing the list afterward.

Sorting with custom keys

fruits = ["apple", "banana", "cherry", "date", "elderberry"]
fruits.sort(key=len)
print(fruits)
['date', 'apple', 'cherry', 'banana', 'elderberry']

The key parameter transforms how Python compares elements during sorting. In this example, key=len tells Python to sort the fruits based on their length instead of alphabetically.

  • Shorter words like "date" (4 letters) appear before longer ones like "elderberry" (10 letters)
  • The key function processes each element before comparison
  • Python applies the key function to all items but preserves the original values in the output

This powerful feature enables custom sorting logic for complex data structures. You can use any function that returns a comparable value as the key—including lambda functions for more sophisticated sorting criteria.

Advanced sorting approaches

Building on the flexibility of custom keys, Python offers three powerful approaches that give developers precise control over complex sorting scenarios—from concise lambda functions to versatile operator modules.

Sorting with lambda functions

people = [("Alice", 25), ("Bob", 19), ("Charlie", 32)]
people.sort(key=lambda x: x[1])
print(people)
[('Bob', 19), ('Alice', 25), ('Charlie', 32)]

Lambda functions enable quick, one-line sorting rules without defining a separate function. In this example, key=lambda x: x[1] tells Python to sort the list of tuples based on the second element (index 1) of each tuple—the age values 19, 25, and 32.

  • The x parameter represents each tuple in the list during sorting
  • x[1] extracts the age value from each tuple
  • Python automatically uses these extracted values to determine the final order

The result shows the tuples arranged by increasing age, with Bob (19) first and Charlie (32) last. The original tuple structure remains intact. This approach works especially well when you need to sort complex data structures based on specific elements or calculated values.

Sorting with functools.cmp_to_key

from functools import cmp_to_key

def compare(a, b):
    return a % 10 - b % 10  # Sort by last digit

numbers = [15, 32, 48, 27, 91]
sorted_numbers = sorted(numbers, key=cmp_to_key(compare))
print(sorted_numbers)
[91, 32, 15, 27, 48]

The cmp_to_key function transforms a comparison function into a key function that Python's sorting algorithms can use. In this example, the compare function sorts numbers based on their last digit using the modulo operator %.

  • The comparison function takes two parameters (a and b) and returns a negative, zero, or positive value
  • A negative return value means a should come before b
  • The modulo operation % 10 extracts the last digit from each number

When Python sorts the list [15, 32, 48, 27, 91], it arranges numbers so their last digits appear in ascending order: 91 (1), 32 (2), 15 (5), 27 (7), 48 (8). This technique proves especially useful when implementing custom comparison logic that can't be achieved with a simple key function.

Sorting with the operator module

import operator

students = [{"name": "Alice", "grade": 85}, {"name": "Bob", "grade": 92}, {"name": "Charlie", "grade": 78}]
sorted_students = sorted(students, key=operator.itemgetter("grade"), reverse=True)
print(sorted_students)
[{'name': 'Bob', 'grade': 92}, {'name': 'Alice', 'grade': 85}, {'name': 'Charlie', 'grade': 78}]

The operator module provides efficient tools for sorting complex data structures. The itemgetter() function creates a callable object that retrieves specific dictionary values, making it ideal for sorting lists of dictionaries.

  • The key=operator.itemgetter("grade") parameter tells Python to sort based on the grade values
  • Setting reverse=True arranges students from highest to lowest grade
  • This approach is more performant than using lambda functions for dictionary key access

The output shows students sorted by their grades in descending order, with Bob's 92 first and Charlie's 78 last. This clean, readable solution works especially well when sorting large datasets of dictionaries or similar nested data structures.

Sorting files by modification date with os.path.getmtime()

The os.path.getmtime() function enables Python to sort files based on their last modification timestamp, creating an organized view of your file system's history that reveals which files you've recently changed.

import os
from datetime import datetime

files = os.listdir('.')
files.sort(key=lambda x: os.path.getmtime(x))
for file in files[:3]:  # Print first 3 files (oldest)
    mod_time = datetime.fromtimestamp(os.path.getmtime(file))
    print(f"{file}: {mod_time.strftime('%Y-%m-%d %H:%M:%S')}")

This code retrieves and displays the three oldest files in your current directory. The os.listdir('.') function gathers all files, while sort() with a lambda function orders them by modification time. The modification timestamp comes from os.path.getmtime(), which returns seconds since the epoch.

  • The datetime.fromtimestamp() converts raw timestamps into readable dates
  • The strftime() method formats these dates into a clear year-month-day hour:minute:second pattern
  • The slice files[:3] selects only the first three entries from the sorted list

This approach creates a simple yet effective way to track your oldest files and understand your directory's chronological structure.

Creating a leaderboard with multiple sorted() criteria

Python's sorting capabilities enable you to build sophisticated leaderboards that rank players by multiple criteria—first by their score in descending order and then by completion time when scores are equal.

players = [
    {"name": "Alice", "score": 192, "time": 45.2},
    {"name": "Bob", "score": 192, "time": 39.8},
    {"name": "Charlie", "score": 156, "time": 42.1},
    {"name": "Diana", "score": 218, "time": 38.6}
]

# Sort by score (descending) and time (ascending) for ties
leaderboard = sorted(players, key=lambda x: (-x["score"], x["time"]))
for rank, player in enumerate(leaderboard, 1):
    print(f"{rank}. {player['name']}: {player['score']} pts ({player['time']}s)")

This code implements a sophisticated sorting system for a list of player dictionaries. The sorted() function uses a tuple-based key parameter to establish a two-tier ranking system.

The negative sign in -x["score"] reverses the score sorting order to achieve descending ranking. When players have equal scores, Python automatically moves to the second tuple element x["time"] to break ties. The enumerate() function then assigns sequential ranking numbers starting from 1.

  • Higher scores take precedence over lower ones
  • For identical scores, faster completion times win
  • The output displays each player's rank, name, score, and time in a formatted string

Common errors and challenges

Python's sorting operations can trigger three common errors that frustrate developers: type mismatches, immutable sequence modifications, and missing dictionary keys.

Dealing with TypeError when sorting mixed types

Python raises a TypeError when you attempt to compare incompatible data types during sorting operations. The error commonly occurs when mixing strings and numbers in the same list. This straightforward example demonstrates what happens when Python tries to sort elements that can't be naturally compared.

mixed_list = [5, "apple", 10, "banana", 2]
mixed_list.sort()
print(mixed_list)

Python can't directly compare strings with integers, so attempting to sort a list containing both types triggers a TypeError. The code below demonstrates an effective way to handle mixed-type sorting.

mixed_list = [5, "apple", 10, "banana", 2]
numbers = sorted([x for x in mixed_list if isinstance(x, int)])
strings = sorted([x for x in mixed_list if isinstance(x, str)])
result = numbers + strings
print(result)

This solution separates mixed-type elements into distinct lists using list comprehension and isinstance() type checking. The code creates two filtered lists: one for integers and another for strings. After sorting each list independently, it combines them with the + operator to produce a clean final result.

  • Watch for this error when working with data from external sources like CSV files or user input
  • The error commonly appears when processing spreadsheet data where numbers are accidentally stored as strings
  • Consider converting all elements to the same type before sorting if uniformity matters for your use case

Handling the AttributeError with immutable sequences

Python's sort() method only works with mutable sequences like lists. When you try to sort an immutable sequence like a tuple, Python raises an AttributeError. The code below demonstrates this common pitfall when working with tuples.

data_tuple = (5, 2, 8, 1, 9)
data_tuple.sort()
print(data_tuple)

The sort() method attempts to modify the tuple directly. Since tuples are immutable Python objects that prevent changes after creation, Python raises an AttributeError. Let's examine the correct approach in the following example.

data_tuple = (5, 2, 8, 1, 9)
sorted_data = sorted(data_tuple)
print(sorted_data)
sorted_tuple = tuple(sorted(data_tuple))
print(sorted_tuple)

The sorted() function creates a new list containing the sorted elements, solving the immutability problem. You can convert the result back to a tuple using the tuple() function if needed. This approach works because sorted() doesn't try to modify the original sequence.

  • Watch for this error when working with data structures from external libraries that return tuples
  • Remember that strings and ranges are also immutable sequences that can't use sort()
  • Consider whether you need the result as a tuple or if a sorted list meets your needs

This pattern appears frequently when processing database results or working with named tuples in data analysis tasks. Always check if your sequence is mutable before attempting to sort it directly.

Handling dictionaries with missing key values

When sorting dictionaries by specific keys, Python raises a KeyError if any dictionary lacks the sorting key. This common issue often surfaces when processing incomplete data from databases or CSV files. The code below demonstrates what happens when sorting a list of student records where one entry lacks a grade.

students = [
    {"name": "Alice", "grade": 85},
    {"name": "Bob"},  # Missing "grade" key
    {"name": "Charlie", "grade": 78}
]
students.sort(key=lambda x: x["grade"])
print(students)

The sort() operation fails because it can't access the grade key in Bob's dictionary. When Python encounters the missing key, it immediately raises a KeyError. The code below demonstrates a robust solution for handling incomplete dictionary data.

students = [
    {"name": "Alice", "grade": 85},
    {"name": "Bob"},  # Missing "grade" key
    {"name": "Charlie", "grade": 78}
]
students.sort(key=lambda x: x.get("grade", 0))
print(students)

The get() method provides a safer way to access dictionary values by returning a default value (0 in this case) when a key doesn't exist. This approach prevents KeyError exceptions and ensures smooth sorting even with incomplete data.

  • Watch for this error when processing data from external sources like APIs or user submissions
  • Consider setting meaningful default values based on your sorting requirements
  • Use this pattern whenever you're unsure about data completeness or consistency

The solution places entries with missing values at the start of the sorted list. You can adjust the default value in get() to control where incomplete records appear in your final sort order.

FAQs

What is the difference between sort() and sorted() when working with lists?

The key difference lies in how these functions modify your data. sort() changes the original list directly and returns None, while sorted() creates a new sorted list without altering the original. This behavior reflects Python's distinction between in-place operations and functions that return new objects.

  • Use sort() when you want to permanently reorder your list and save memory
  • Choose sorted() when you need to preserve the original list order or chain operations together

How can you sort a list in descending order instead of ascending?

To sort a list in descending order, add the reverse=True parameter to Python's built-in sort() method or use the sorted() function. This tells Python to arrange elements from highest to lowest instead of the default lowest to highest.

  • For lists, use my_list.sort(reverse=True) to modify the original list directly
  • For a new sorted copy, use sorted(my_list, reverse=True)

The reverse parameter works by inverting the comparison operations Python uses during the sorting process. This approach maintains the efficiency of Python's sorting algorithm while giving you the flexibility to sort in either direction.

Can you sort a list that contains both numbers and strings together?

Python's default sort() and sorted() functions can't directly compare numbers and strings. When you try this, Python raises a TypeError because it doesn't know how to compare these different data types meaningfully.

To sort mixed lists, you'll need to implement a custom sorting key that handles each type appropriately. The most common approach uses a tuple key that first groups items by type, then sorts within each type. This preserves a natural ordering while preventing type comparison errors.

What happens to the original list when you use the sort() method?

The sort() method modifies the original list directly instead of creating a new sorted copy. This in-place sorting means the list's elements get rearranged in their memory locations. When you call sort(), Python's algorithm compares and swaps elements until they're in the specified order.

Understanding this behavior is crucial for memory efficiency. Since Python doesn't need to allocate new memory for a copy, in-place sorting works well for large datasets. However, if you need to preserve the original order, use the sorted() function instead—it returns a new sorted list while leaving the original untouched.

How do you sort a list of strings alphabetically ignoring case sensitivity?

To sort strings alphabetically while ignoring case, use the sort() method with a key function that converts each string to lowercase. The key=str.lower parameter tells the sorting algorithm to compare lowercase versions of the strings while maintaining their original case in the output. This approach works because Python's string comparison follows Unicode ordering—making it reliable across different character sets.

The sorting process happens in two logical steps: first converting each string temporarily to lowercase for comparison, then rearranging the original strings based on those lowercase comparisons. This preserves the original formatting while achieving case-insensitive ordering.

🏠