Skip to main content

How to Get Indices of a Sorted List in Python

Often, you need to know the indices that would sort a list, rather than sorting the list itself. This is useful for reordering other related lists or for advanced indexing operations.

This guide explores how to obtain the indices that would sort a list in Python, covering both built-in methods and the efficient numpy.argsort() approach.

Using sorted() with range() and a lambda (General Approach)

The most general and flexible way to get the indices of a sorted list (without actually sorting the original list) involves these steps:

  • Create a range object with the same length as your list. This represents the original indices.
  • Use the sorted() function on this range, but provide a key function.
  • The key function is a lambda that takes an index and returns the corresponding value from the original list. This tells sorted() to sort based on the list values, but the output will be the sorted indices.
a_list = ['a', 'b', 'd', 'c']

indices = sorted(range(len(a_list)), key=lambda index: a_list[index])
print(indices) # Output: [0, 1, 3, 2]

# You can then use these indices to create a sorted list:
sorted_list = [a_list[index] for index in indices]
print(sorted_list) # Output: ['a', 'b', 'c', 'd']


# Example with numbers
a_list = [1, 2, 4, 3]

indices = sorted(range(len(a_list)), key=lambda index: a_list[index])
print(indices) # Output: [0, 1, 3, 2]
sorted_list = [a_list[index] for index in indices]
print(sorted_list) # Output: [1, 2, 3, 4]
  • The range(len(a_list)) creates a sequence of numbers that represent the indices in the original list.
  • The sorted() function takes the range object and a key argument.
  • key=lambda index: a_list[index] This is crucial. The lambda function takes an index as input and returns the value at that index in the original list a_list. This tells sorted() to sort based on the values in a_list, but to return the sorted indices.
  • The result will be a list of sorted indices, which can be used to create a new, sorted list if needed.

If you're working with numerical data and have NumPy installed, numpy.argsort() is the most efficient way to get the sorted indices:

import numpy as np

a_list = ['a', 'b', 'd', 'c'] # Can also be a list of numbers
indices = np.argsort(a_list)
print(indices) # Output: [0 1 3 2] (NumPy array of indices)

# Create a sorted list using the indices:
sorted_list = [a_list[index] for index in indices] # Or, with numpy: sorted_arr = np.array(a_list)[indices]
print(sorted_list) # Output: ['a', 'b', 'c', 'd']

#You can also convert the indices to a list:
indices_list = np.argsort(a_list).tolist()
print(indices_list) # Output: [0, 1, 3, 2]
  • np.argsort(a_list): Returns a NumPy array of indices that would sort a_list. This is highly optimized for numerical data.
  • The sorted list can then be created using list comprehension and the indices list.
  • You can also use np.array(a_list)[indices] to apply the sorting directly using NumPy, which would be even more efficient.
  • The tolist() can be used to convert the ndarray object to a list.
note

When to use NumPy: If you're working with numerical data (especially large arrays) and already have NumPy installed, np.argsort() is significantly faster than the pure-Python approaches. If you're dealing with strings or mixed data types, or if you don't have NumPy, the sorted(range(...), key=...) method is the best general-purpose solution.

Using enumerate() and sorted() (Less Efficient)

While functional, this approach is more complex and generally less efficient than the previous methods:

a_list = ['a', 'b', 'd', 'c']

indices = [
tup[0] for tup
in sorted(enumerate(a_list), key=lambda x: x[1])
]
print(indices) # Output: [0, 1, 3, 2]
sorted_list = [a_list[index] for index in indices]
print(sorted_list) # Output: ['a', 'b', 'c', 'd']
  • enumerate(a_list): Pairs each element with its index: [(0, 'a'), (1, 'b'), (2, 'd'), (3, 'c')]
  • sorted(..., key=lambda x: x[1]): Sorts this list of tuples based on the second element of each tuple (the original list value).
  • [tup[0] for tup in ...]: Extracts the first element (the original index) from each sorted tuple.

This method is included for completeness, but it's generally less readable and less efficient than using sorted(range(...), key=...) or np.argsort().