Skip to content

An In-Depth Guide to Sorting Lists in Python

Updated: at 05:12 AM

Lists are one of the fundamental data structures in Python. Often we need to sort the elements of a list in a particular order - either ascending or descending. Python provides many flexible and efficient ways to sort lists. This article will provide an in-depth look at the various methods for sorting lists in Python.

Table of Contents

Open Table of Contents

Overview of Sorting Lists in Python

There are two main ways to sort lists in Python:

  1. Using the sorted() function to return a new sorted list copy leaving the original list unchanged.

  2. Using the list.sort() method to sort a list in-place, mutating the original list.

Additionally, we can customize how lists are sorted by providing a key function that transforms each element before comparing them. This allows advanced sorting logic rather than just sorting by the natural order.

Below we will explore practical examples of each method along with sample code snippets. But first, let’s understand how sorting works in Python.

How Sorting Works in Python

Before using the sorting methods, it helps to know a bit about their implementation under the hood.

Python’s sorting algorithms rely on the __lt__() (less than) method to compare elements. This method returns True if one element should be sorted before another.

For example:

5 __lt__(10) # Returns True

This implies that 5 should be sorted before 10. Python sorts the list by recursively making these comparisons for each pair of elements.

For custom classes, we can override the __lt__() method to define custom sorting logic.

Now let’s see how to leverage these techniques for sorting lists in practice.

The sorted() Function

The simplest way to get a sorted version of a list is to use the built-in sorted() function.

Syntax

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

Example Usage

# List of numbers
numbers = [5, 1, 4, 2, 3]

sorted_numbers = sorted(numbers)
print(sorted_numbers)

# Output: [1, 2, 3, 4, 5]

The sorted() function returns a new list containing the elements of the original iterable in sorted order.

Let’s look at a few more examples.

# String
sorted_string = sorted("Python")
print(sorted_string)

# Output: ['P', 'h', 'n', 'o', 't', 'y']


# Tuple
numbers = (5, 1, 4, 2, 3)
sorted_numbers = sorted(numbers)
print(sorted_numbers)

# Output: [1, 2, 3, 4, 5]

sorted() can sort any iterable object, including tuples which normally cannot be modified.

One important point is that sorted() does not modify the original object - it returns a new sorted object instead. So the original list or tuple remains unchanged.

Custom Sorting with key Parameter

To customize how the elements are sorted, we can use the key parameter to provide a function that transforms each element before comparing them.

For example, to sort a list of strings ignoring case:

names = ["John", "mark", "tom", "Amanda"]

sorted_names = sorted(names, key=str.lower)

print(sorted_names)

# Output: ['Amanda', 'John', 'mark', 'tom']

Here we pass the str.lower function as the key which converts each name to lower case before comparing them. This results in a case-insensitive sorting.

The key function takes in a single element and returns a value to be used for comparisons in sorting. This allows powerful flexibility to customize sorting order.

Some more examples:

# Sort list of tuples by second item
tuples = [(1, 4), (3, 7), (2, 5)]

sorted_tuples = sorted(tuples, key=lambda x: x[1])

print(sorted_tuples)

# Output: [(1, 4), (2, 5), (3, 7)]


# Sort strings by length
strings = ["Python", "Java", "C++", "Rust"]

sorted_strings = sorted(strings, key=len)

print(sorted_strings)

# Output: ['C++', 'Java', 'Python', 'Rust']

The key function provides unlimited possibilities for advanced sorting logic.

Sorting in Reverse

To sort the elements in reverse or descending order, we can set the reverse flag to True.

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

sorted_numbers = sorted(numbers, reverse=True)

print(sorted_numbers)

# Output: [5, 4, 3, 2, 1]

The reverse flag tells sorted() to reverse the comparisons while sorting the elements.

We can combine reverse=True with a custom key function to get a descending order with custom sorting logic.

Complexity

The sorted() function has a time complexity of O(n log n) - efficient even for large lists.

In summary, sorted() is ideal when:

Next, let’s see how to sort a list in-place.

The list.sort() Method

For mutating sorting that changes the original list object, we can use the list.sort() method.

Syntax

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

Example Usage

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

numbers.sort()
print(numbers)

# Output: [1, 2, 3, 4, 5]

Unlike sorted(), list.sort() sorts the list in-place and does not return anything. The original list is permanently changed into the sorted order.

Let’s see a few more examples:

names = ["John", "mark", "tom", "Amanda"]

names.sort(key=str.lower)
print(names)

# Output: ['Amanda', 'John', 'mark', 'tom']


products = [('Banana', 1), ('Orange', 5), ('Apple', 4)]

products.sort(key=lambda x: x[1])
print(products)

# Output: [('Banana', 1), ('Apple', 4), ('Orange', 5)]

We can use key and reverse similar to sorted() to customize sorting logic.

Complexity

The .sort() method has worst case time complexity of O(n log n) - efficient for large lists.

In summary, list.sort() is ideal when:

Now let’s look at how to leverage these techniques to sort some real-world examples.

Practical Examples of Sorting Lists in Python

Let’s go through some practical code examples of sorting common list data types in Python.

Example 1: Sort a List of Integers

numbers = [15, 6, 18, 2, 45, 10, 8]

# Ascending order
numbers.sort()
print(numbers)

# Output: [2, 6, 8, 10, 15, 18, 45]


# Descending order
numbers.sort(reverse=True)
print(numbers)

# Output: [45, 18, 15, 10, 8, 6, 2]

To sort integers we can simply use the default natural ordering.

Example 2: Sort a List of Strings

names = ["Mark", "john", "tom", "Amanda", "Ron"]

# Ascending case-insensitive order
names.sort(key=str.lower)
print(names)

# Output: ['Amanda', 'john', 'Mark', 'Ron', 'tom']


# Descending case-sensitive order
names.sort(key=str.lower, reverse=True)
print(names)

# Output: ['tom', 'Ron', 'Mark', 'john', 'Amanda']

For strings, we used str.lower as key for case-insensitive sorting.

Example 3: Sort a List of Tuples

products = [('Apple', 200), ('Orange', 160), ('Banana', 50)]

# Sort by price ascending
products.sort(key=lambda x: x[1])
print(products)

# Output: [('Banana', 50), ('Orange', 160), ('Apple', 200)]


# Sort by name descending
products.sort(key=lambda x: x[0], reverse=True)
print(products)

# Output: [('Orange', 160), ('Banana', 50), ('Apple', 200)]

For tuples, we used a lambda key function to access the indexed item to sort by.

Example 4: Sort a List of Dicts

employees = [
  {'Name': 'John', 'Age': 28},
  {'Name': 'Jane', 'Age': 30},
  {'Name': 'Jack', 'Age': 26}
]

# Sort by Age ascending
employees.sort(key=lambda x: x['Age'])
print(employees)

# Output: [{'Name': 'Jack', 'Age': 26},
          {'Name': 'John', 'Age': 28},
          {'Name': 'Jane', 'Age': 30}]

# Sort by Name descending
employees.sort(key=lambda x: x['Name'], reverse=True)
print(employees)

# Output: [{'Name': 'John', 'Age': 28},
          {'Name': 'Jack', 'Age': 26},
          {'Name': 'Jane', 'Age': 30}]

For dictionaries, we passed a lambda to access the value of the desired key for sorting.

Example 5: Sort a List of Objects

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

people = [
  Person('John', 28),
  Person('Jack', 26),
  Person('Jane', 30)
]

# Sort by age
people.sort(key=lambda x: x.age)
print(people)

# Output: [Person('Jack', 26), Person('John', 28), Person('Jane', 30)]

# Sort by name descending
people.sort(key=lambda x: x.name, reverse=True)
print(people)

# Output: [Person('John', 28), Person('Jack', 26), Person('Jane', 30)]

For custom class objects, we access the attributes inside the lambda function to define sorting logic.

These examples demonstrate how we can sort common Python data types in practice.

Conclusion

In summary, Python provides highly efficient and flexible ways to sort lists using sorted(), list.sort(), and custom key functions.

The key takeaways are:

With this comprehensive guide, you should feel confident applying these techniques for sorting tasks in Python coding and data analysis. The built-in sorting functionality makes it easy to work with sorted data.

Happy Python coding!