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 thisrange
, but provide akey
function. - The
key
function is alambda
that takes an index and returns the corresponding value from the original list. This tellssorted()
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. Thelambda
function takes an index as input and returns the value at that index in the original lista_list
. This tellssorted()
to sort based on the values ina_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.
Using numpy.argsort()
(Recommended for Numerical Data)
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 sorta_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 thendarray
object to a list.
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()
.