Sort a Python List of Lists by the Second Element

Sort a Python list of lists by its second or any other element using sorted(), list.sort(), lambda expressions and itemgetter.

Sort a list of lists by the second element with sorted() and a key function:

rows = [["third", 3], ["first", 1], ["second", 2]]

ordered = sorted(rows, key=lambda row: row[1])
print(ordered)
# [['first', 1], ['second', 2], ['third', 3]]

Index 1 means the second element because Python indexes begin at zero.

sorted() versus .sort()

sorted() returns a new list and leaves the original unchanged:

ordered = sorted(rows, key=lambda row: row[1])

.sort() changes the original list in place and returns None:

rows.sort(key=lambda row: row[1])

Use sorted() when other code still needs the original order. Use .sort() when the list should be permanently reordered.

Sort in descending order

Set reverse=True:

ordered = sorted(rows, key=lambda row: row[1], reverse=True)

Sort by another element

Change the index used by the key function:

# First element
sorted(rows, key=lambda row: row[0])

# Third element
sorted(rows, key=lambda row: row[2])

Every row must contain the selected index or Python will raise IndexError.

The same key functions work on lists of tuples—see sorting a list of tuples by the first element. If the sort criterion is a property of the value rather than an index, pass a different key function, as in sorting a list by string length.

Use itemgetter()

operator.itemgetter() expresses the same intent without a lambda:

from operator import itemgetter

ordered = sorted(rows, key=itemgetter(1))

Both versions are valid. A lambda is familiar and flexible; itemgetter() is concise when you only need elements by index.

Sort numeric strings as numbers

Strings sort alphabetically, so "10" appears before "2". Convert the key when the values represent numbers:

rows = [["A", "10"], ["B", "2"], ["C", "1"]]
ordered = sorted(rows, key=lambda row: int(row[1]))

Validate untrusted strings before converting them. See how to check whether a string converts to an integer.

Missing or None values

Give missing values an explicit position:

rows = [["A", 3], ["B", None], ["C", 1]]

ordered = sorted(
    rows,
    key=lambda row: (row[1] is None, row[1] if row[1] is not None else 0),
)

The first tuple value places real numbers before None. The second sorts the real numbers.

Ties keep their original order

Python’s sort is stable: rows with equal second elements stay in the order they appeared in the original list.

rows = [["b", 1], ["a", 2], ["c", 1]]
print(sorted(rows, key=lambda row: row[1]))
# [['b', 1], ['c', 1], ['a', 2]]

["b", 1] stays ahead of ["c", 1] because it came first. Stability also means you can sort twice—first by the tie-breaker, then by the main key—and the second sort preserves the first sort’s order within ties.

For several sort columns or mixed ascending and descending rules, continue with sorting a list of lists by multiple columns. For rows that are dictionaries rather than lists, see sorting a list of dictionaries by key.