Sort a Python List of Lists by Multiple Columns
Sort a Python list of lists by multiple columns using tuple keys, itemgetter, mixed ascending and descending order, and missing-value handling.
Sort a Python list of lists by multiple columns by returning a tuple from the key function:
rows = [
["Sydney", "Python", 3],
["London", "Python", 1],
["Sydney", "Excel", 2],
]
ordered = sorted(rows, key=lambda row: (row[0], row[1]))
Python compares the first tuple value, then uses the second to break ties.
Sort by two numeric columns
scores = [["A", 90, 4], ["B", 90, 2], ["C", 80, 1]]
ordered = sorted(scores, key=lambda row: (row[1], row[2]))
Sort one column descending
Negate a numeric key to reverse only that part of the order:
# Score descending, attempts ascending
ordered = sorted(scores, key=lambda row: (-row[1], row[2]))
Using reverse=True would reverse every component, not just the score.
Sort strings descending and numbers ascending
For mixed directions that cannot use numeric negation, apply stable sorts from the least important key to the most important:
rows.sort(key=lambda row: row[2])
rows.sort(key=lambda row: row[0], reverse=True)
Python’s sort is stable, so the second operation keeps the earlier ordering when the primary values are equal.
Use itemgetter() for several columns
from operator import itemgetter
ordered = sorted(rows, key=itemgetter(0, 1))
This is equivalent to returning (row[0], row[1]) from a lambda.
Handle case-insensitive text
ordered = sorted(rows, key=lambda row: (row[0].casefold(), row[1].casefold()))
casefold() is a strong default for case-insensitive Unicode comparisons.
Handle missing values
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),
)
This places None after real numbers. Reverse the first boolean if missing values should appear first.
Start with the simpler guide to sorting by the second or nth element when only one column controls the order.