
Sorting lists in Python is one of the most common operations you will perform when working with collections of data. Python sort lists using two primary approaches that give you full control over how your data gets organized. The built-in sort method and the sorted function let you arrange elements in ascending order, descending order, or any custom order you define. Whether you are working with numbers, strings, or complex objects, knowing how to sort lists in Python will help you write cleaner and more efficient programs.
Python makes sorting incredibly simple compared to many other programming languages. You can sort a list of numbers from smallest to largest with a single method call, or you can define your own sorting logic using a key function. The flexibility of Python list sorting means you can handle virtually any ordering requirement without writing your own sorting algorithm from scratch.
The sort method is the most direct way to sort lists in Python. It modifies the original list in place, which means it rearranges the elements directly in the existing list rather than creating a new one. This makes it memory efficient because no additional list is created during the operation.
numbers = [42, 17, 8, 35, 3, 21]
numbers.sort()
print(numbers)
Output
[3, 8, 17, 21, 35, 42]
The sort method arranged all the numbers from smallest to largest. Since sort works in place, the original list is now permanently changed. This is an important distinction to remember when you sort lists in Python because if you need to keep the original order, you should use the sorted function instead.
The sort method works equally well with strings. When you sort a list of strings, Python arranges them in alphabetical order based on their Unicode code points.
cities = ["Toronto", "Mumbai", "Berlin", "Auckland", "Cairo"]
cities.sort()
print(cities)
Output
['Auckland', 'Berlin', 'Cairo', 'Mumbai', 'Toronto']
The cities are now arranged in alphabetical order. Python compares strings character by character using their Unicode values, so uppercase letters come before lowercase letters when mixing cases.
Python sort lists in descending order using the reverse parameter. Setting reverse to True tells the sort method to arrange elements from largest to smallest for numbers, or in reverse alphabetical order for strings. This is much cleaner than sorting and then reversing separately.
scores = [88, 45, 92, 73, 61, 97, 55]
scores.sort(reverse=True)
print(scores)
Output
[97, 92, 88, 73, 61, 55, 45]
The scores are now arranged from highest to lowest. The reverse parameter is a simple boolean flag that flips the entire sort order without requiring any additional code.
You can also sort strings in reverse alphabetical order using the same approach.
languages = ["Python", "Java", "Rust", "Go", "Swift", "C"]
languages.sort(reverse=True)
print(languages)
Output
['Swift', 'Rust', 'Python', 'Java', 'Go', 'C']
The reverse parameter works with any data type that supports comparison, making it a universal way to sort lists in descending order in Python.
The sorted function is the second way to sort lists in Python, and it differs from the sort method in one crucial way. Instead of modifying the original list, sorted creates and returns a brand new sorted list while leaving the original unchanged. This is especially useful when you need both the original and sorted versions of your data.
temperatures = [72, 58, 91, 64, 83, 47]
sorted_temps = sorted(temperatures)
print("Original:", temperatures)
print("Sorted:", sorted_temps)
Output
Original: [72, 58, 91, 64, 83, 47]
Sorted: [47, 58, 64, 72, 83, 91]
The original temperatures list remains completely untouched while sorted_temps contains the ordered version. This non-destructive behavior makes sorted the preferred choice when you need to preserve your original data while also working with a sorted version.
The sorted function also accepts the reverse parameter just like the sort method.
prices = [29.99, 9.50, 45.00, 12.75, 67.30]
descending_prices = sorted(prices, reverse=True)
print(descending_prices)
Output
[67.3, 45.0, 29.99, 12.75, 9.5]
The sorted function gives you the same flexibility as the sort method but with the added benefit of keeping your original data intact. You can sort lists in Python using either approach depending on whether you need the original order preserved.
The key parameter is where Python list sorting becomes truly powerful. You can pass a function to the key parameter, and Python will use the return value of that function to determine the sort order. This lets you sort lists by any criteria you can define in a function.
Sorting a list of strings by their length is a common use case for the key parameter.
animals = ["elephant", "cat", "hippopotamus", "dog", "butterfly", "ox"]
animals.sort(key=len)
print(animals)
Output
['ox', 'cat', 'dog', 'elephant', 'butterfly', 'hippopotamus']
Instead of sorting alphabetically, Python sorted the list by the length of each string. The len function is called on each element, and the returned length values are used for comparison. The shortest words appear first and the longest words appear last.
You can use lambda functions as the key for more specific sorting logic. For example, sorting a list of strings by their last character.
words = ["apple", "mango", "grape", "peach", "berry"]
words.sort(key=lambda w: w[-1])
print(words)
Output
['grape', 'apple', 'mango', 'peach', 'berry']
The lambda function extracts the last character of each word, and Python uses those characters to determine the order. This demonstrates how the key parameter lets you sort lists in Python using any property or transformation of the elements.
When you work with structured data, you often need to sort lists of tuples in Python. Each tuple might represent a record with multiple fields, and you can choose which field to sort by using the key parameter.
students = [("Alice", 88), ("David", 72), ("Bella", 95), ("Charlie", 81)]
students.sort(key=lambda student: student[1])
print(students)
Output
[('David', 72), ('Charlie', 81), ('Alice', 88), ('Bella', 95)]
The lambda function extracts the second element (index 1) from each tuple, which represents the score. Python sort lists of tuples by comparing these extracted values, so students are now arranged from lowest to highest score.
You can also sort by the first element or any other index within the tuples.
products = [("Keyboard", 49.99), ("Mouse", 24.99), ("Monitor", 199.99), ("Cable", 8.50)]
products.sort(key=lambda p: p[0])
print(products)
Output
[('Cable', 8.5), ('Keyboard', 49.99), ('Monitor', 199.99), ('Mouse', 24.99)]
The products are sorted alphabetically by their name, which is the first element of each tuple. Sorting tuples is an essential skill when you sort lists in Python that contain structured data.
The operator module provides itemgetter and attrgetter functions that are more efficient and readable alternatives to lambda functions for sorting. When sorting lists of tuples or dictionaries, itemgetter is particularly clean.
from operator import itemgetter
employees = [("Sara", "Engineering", 75000), ("Tom", "Marketing", 62000), ("Lin", "Engineering", 89000), ("Max", "Sales", 58000)]
employees.sort(key=itemgetter(2))
print(employees)
Output
[('Max', 'Sales', 58000), ('Tom', 'Marketing', 62000), ('Sara', 'Engineering', 75000), ('Lin', 'Engineering', 89000)]
The itemgetter(2) function retrieves the element at index 2 from each tuple, which is the salary. This achieves the same result as a lambda function but is faster and easier to read. Using itemgetter is a professional approach to sort lists in Python when dealing with indexed data structures.
You can even sort by multiple keys with itemgetter by passing multiple indices.
from operator import itemgetter
records = [("Sara", "Engineering", 75000), ("Tom", "Engineering", 62000), ("Lin", "Marketing", 89000), ("Max", "Engineering", 58000)]
records.sort(key=itemgetter(1, 2))
print(records)
Output
[('Max', 'Engineering', 58000), ('Tom', 'Engineering', 62000), ('Sara', 'Engineering', 75000), ('Lin', 'Marketing', 89000)]
The records are first sorted by department (index 1) alphabetically, and within the same department, they are sorted by salary (index 2) in ascending order. This multi-key sorting is extremely useful for organizing complex data.
When you sort lists of strings in Python, uppercase and lowercase letters are treated differently by default. All uppercase letters have lower Unicode values than lowercase letters, which means "Zebra" would come before "apple" in a default sort. To sort lists without case sensitivity, use the str.lower method as the key.
names = ["alice", "Charlie", "bob", "Diana", "eve"]
names.sort(key=str.lower)
print(names)
Output
['alice', 'bob', 'Charlie', 'Diana', 'eve']
By passing str.lower as the key function, Python converts each string to lowercase temporarily for comparison purposes only. The original strings in the list remain unchanged with their original casing. This is the standard way to perform case-insensitive sorting when you sort lists in Python that contain mixed-case strings.
Sorting a list of dictionaries is a frequent task in real-world Python programming. Each dictionary might represent a record with named fields, and you sort by accessing specific keys.
books = [
{"title": "The Great Gatsby", "year": 1925},
{"title": "To Kill a Mockingbird", "year": 1960},
{"title": "1984", "year": 1949},
{"title": "Brave New World", "year": 1932}
]
books.sort(key=lambda b: b["year"])
for book in books:
print(f"{book['title']} ({book['year']})")
Output
The Great Gatsby (1925)
Brave New World (1932)
1984 (1949)
To Kill a Mockingbird (1960)
The lambda function accesses the year key from each dictionary, and Python uses those year values to determine the sort order. You can sort lists of dictionaries in Python by any key using this same pattern. Simply change the dictionary key in the lambda to sort by a different field.
Python uses Timsort, a stable sorting algorithm. Stable sorting means that when two elements have equal sort keys, they maintain their original relative order from the unsorted list. This property is incredibly useful when you need to sort by multiple criteria in sequence.
tasks = [("Write report", 2), ("Fix bug", 1), ("Code review", 2), ("Deploy app", 1), ("Update docs", 3)]
tasks.sort(key=lambda t: t[1])
print(tasks)
Output
[('Fix bug', 1), ('Deploy app', 1), ('Write report', 2), ('Code review', 2), ('Update docs', 3)]
Notice that among the priority 1 tasks, "Fix bug" still appears before "Deploy app", which was their original order. Similarly, "Write report" appears before "Code review" among the priority 2 tasks. This stability guarantee means you can sort lists in Python by multiple criteria by performing successive sorts, starting with the least important criterion and ending with the most important one.
Sometimes you need to reverse the order of an already sorted list, or you want to iterate over a list in reverse sorted order. Python provides the reverse method and the reversed function for these scenarios.
values = [15, 42, 8, 23, 37, 4]
values.sort()
print("Ascending:", values)
values.reverse()
print("Descending:", values)
Output
Ascending: [4, 8, 15, 23, 37, 42]
Descending: [42, 37, 23, 15, 8, 4]
The reverse method flips the list in place after sorting. While you could achieve the same result with sort(reverse=True), there are situations where reversing a previously sorted list is more convenient, such as when you receive an already-sorted list and need the opposite order.
This example demonstrates all the major ways to sort lists in Python, including the sort method, the sorted function, custom key functions, sorting tuples, sorting dictionaries, and descending order sorting.
from operator import itemgetter
inventory = [
{"name": "Laptop", "price": 899.99, "quantity": 15},
{"name": "Mouse", "price": 24.99, "quantity": 150},
{"name": "Keyboard", "price": 74.50, "quantity": 85},
{"name": "Monitor", "price": 349.00, "quantity": 30},
{"name": "Webcam", "price": 59.99, "quantity": 60},
{"name": "Headset", "price": 129.00, "quantity": 45}
]
sorted_by_price = sorted(inventory, key=lambda item: item["price"])
print("Sorted by price (ascending):")
for product in sorted_by_price:
print(f" {product['name']}: ${product['price']:.2f}")
print()
sorted_by_quantity_desc = sorted(inventory, key=lambda item: item["quantity"], reverse=True)
print("Sorted by quantity (descending):")
for product in sorted_by_quantity_desc:
print(f" {product['name']}: {product['quantity']} units")
print()
sorted_by_name = sorted(inventory, key=lambda item: item["name"].lower())
print("Sorted by name (case-insensitive):")
for product in sorted_by_name:
print(f" {product['name']}")
print()
sales_data = [("Laptop", "Q1", 12000), ("Mouse", "Q1", 5400), ("Laptop", "Q2", 15000), ("Mouse", "Q2", 6100), ("Keyboard", "Q1", 3200), ("Keyboard", "Q2", 4800)]
sales_data_sorted = sorted(sales_data, key=itemgetter(0, 1))
print("Sales data sorted by product then quarter:")
for record in sales_data_sorted:
print(f" {record[0]} - {record[1]}: ${record[2]}")
print()
numbers = [64, 25, 12, 22, 11, 90, 47]
ascending = sorted(numbers)
descending = sorted(numbers, reverse=True)
by_last_digit = sorted(numbers, key=lambda n: n % 10)
print(f"Original: {numbers}")
print(f"Ascending: {ascending}")
print(f"Descending: {descending}")
print(f"By last digit: {by_last_digit}")
print()
words = ["Banana", "apple", "cherry", "Date", "elderberry"]
default_sort = sorted(words)
case_insensitive = sorted(words, key=str.lower)
by_length = sorted(words, key=len)
print(f"Default sort: {default_sort}")
print(f"Case-insensitive: {case_insensitive}")
print(f"By length: {by_length}")
Output
Sorted by price (ascending):
Mouse: $24.99
Webcam: $59.99
Keyboard: $74.50
Headset: $129.00
Monitor: $349.00
Laptop: $899.99
Sorted by quantity (descending):
Mouse: 150 units
Keyboard: 85 units
Webcam: 60 units
Headset: 45 units
Monitor: 30 units
Laptop: 15 units
Sorted by name (case-insensitive):
Headset
Keyboard
Laptop
Monitor
Mouse
Webcam
Sales data sorted by product then quarter:
Keyboard - Q1: $3200
Keyboard - Q2: $4800
Laptop - Q1: $12000
Laptop - Q2: $15000
Mouse - Q1: $5400
Mouse - Q2: $6100
Original: [64, 25, 12, 22, 11, 90, 47]
Ascending: [11, 12, 22, 25, 47, 64, 90]
Descending: [90, 64, 47, 25, 22, 12, 11]
By last digit: [90, 11, 12, 22, 64, 25, 47]
Default sort: ['Banana', 'Date', 'apple', 'cherry', 'elderberry']
Case-insensitive: ['apple', 'Banana', 'cherry', 'Date', 'elderberry']
By length: ['Date', 'apple', 'Banana', 'cherry', 'elderberry']