How to sort a list of lists by a specific index of the inner list?
Categories:
How to Sort a List of Lists by a Specific Inner List Index in Python

Learn various Python techniques, including sort()
, sorted()
, and itemgetter
, to efficiently sort lists containing other lists based on the value at a particular index within the inner lists.
Sorting a list of lists is a common task in Python, especially when dealing with tabular data or records where each inner list represents a row and its elements are columns. Often, you'll need to sort this data not by the first element, but by a specific 'column' or index within each inner list. This article will guide you through several effective methods to achieve this, from basic lambda
functions to more optimized approaches using operator.itemgetter
.
Understanding the Problem: Sorting by an Inner List Element
Imagine you have a list of student records, where each record is a list containing [name, age, grade]
. If you want to sort these students by their age (which is at index 1 of each inner list) or by their grade (at index 2), you can't simply use Python's default sorting mechanism. The default sort would compare the inner lists lexicographically, starting from index 0. To sort by a specific index, you need to provide a 'key' function that tells Python what part of each inner list to use for comparison.
flowchart TD A["Original List of Lists"] B["Sort Function (e.g., sorted() or .sort())"] C["Key Function (e.g., lambda or itemgetter)"] D["Inner List Element at Specified Index"] E["Comparison Logic"] F["Sorted List of Lists"] A --> B B --> C C --> D D --> E E --> B B --> F
Flowchart illustrating the process of sorting a list of lists using a key function.
Method 1: Using sorted()
with a lambda
function
The sorted()
built-in function returns a new sorted list from the items in an iterable. It takes an optional key
argument, which is a function that will be called on each list element prior to making comparisons. A lambda
function is perfect for this, as it allows you to define a small, anonymous function inline.
data = [
['apple', 3, 10],
['banana', 1, 5],
['cherry', 2, 8]
]
# Sort by the element at index 1 (the number in the middle)
# The lambda function `lambda x: x[1]` tells sorted() to use the second element (index 1) of each inner list for sorting.
sorted_data_by_index_1 = sorted(data, key=lambda x: x[1])
print(f"Sorted by index 1: {sorted_data_by_index_1}")
# Sort by the element at index 2 (the last number)
sorted_data_by_index_2 = sorted(data, key=lambda x: x[2])
print(f"Sorted by index 2: {sorted_data_by_index_2}")
# Sort in reverse order by index 1
sorted_data_reverse = sorted(data, key=lambda x: x[1], reverse=True)
print(f"Sorted by index 1 (reverse): {sorted_data_reverse}")
Sorting a list of lists using sorted()
with a lambda
function.
sorted()
function returns a new list, leaving the original list unchanged. If you need to sort the list in-place, use the list.sort()
method instead.Method 2: Using list.sort()
with a lambda
function
The list.sort()
method sorts the list in-place, meaning it modifies the original list directly and returns None
. Like sorted()
, it also accepts a key
argument for custom sorting logic.
data = [
['apple', 3, 10],
['banana', 1, 5],
['cherry', 2, 8]
]
print(f"Original data: {data}")
# Sort in-place by the element at index 0 (the string)
data.sort(key=lambda x: x[0])
print(f"Sorted in-place by index 0: {data}")
# Reset data for another sort example
data = [
['apple', 3, 10],
['banana', 1, 5],
['cherry', 2, 8]
]
# Sort in-place by the element at index 1
data.sort(key=lambda x: x[1])
print(f"Sorted in-place by index 1: {data}")
Sorting a list of lists in-place using list.sort()
with a lambda
function.
Method 3: Using operator.itemgetter
for Performance
While lambda
functions are concise and readable, for performance-critical applications or very large lists, operator.itemgetter
can be more efficient. itemgetter
returns a callable object that fetches the item at the specified index (or indices) from its operand. It's equivalent to a lambda
function but implemented in C, making it faster.
from operator import itemgetter
data = [
['apple', 3, 10],
['banana', 1, 5],
['cherry', 2, 8]
]
# Sort by the element at index 1 using itemgetter
sorted_data_itemgetter = sorted(data, key=itemgetter(1))
print(f"Sorted by index 1 (itemgetter): {sorted_data_itemgetter}")
# Sort by the element at index 2 using itemgetter
sorted_data_itemgetter_2 = sorted(data, key=itemgetter(2))
print(f"Sorted by index 2 (itemgetter): {sorted_data_itemgetter_2}")
# You can also sort by multiple keys (e.g., primary sort by index 1, secondary sort by index 0)
data_multi_key = [
['apple', 3, 10],
['banana', 1, 5],
['cherry', 2, 8],
['date', 3, 7]
]
sorted_data_multi_key = sorted(data_multi_key, key=itemgetter(1, 0))
print(f"Sorted by index 1 then index 0: {sorted_data_multi_key}")
Sorting a list of lists using operator.itemgetter
.
itemgetter(1, 0)
, Python first sorts by the element at index 1. If two elements have the same value at index 1, it then uses the element at index 0 to break the tie.Choosing the Right Method
The choice between lambda
and itemgetter
largely depends on your specific needs:
- Readability and Simplicity: For simple sorting criteria,
lambda
functions are often more intuitive and easier to read, especially for those less familiar with theoperator
module. - Performance: For very large datasets or performance-critical applications,
operator.itemgetter
is generally faster because it's implemented in C. - In-place vs. New List: Use
list.sort()
if you want to modify the original list and save memory. Usesorted()
if you need a new sorted list and want to preserve the original.
IndexError
.