sorted(numbers) works on a list of comparable values — numbers, strings. What about a list of dicts?
rows = [{"k": "b"}, {"k": "a"}, {"k": "c"}]
sorted(rows) # TypeError — Python doesn't know how to compare dictsRight, no natural ordering on dicts.
That's where the key= parameter comes in. You give sorted a function that takes one item and returns the value to sort by:
sorted(rows, key=lambda r: r["k"])
# [{'k': 'a'}, {'k': 'b'}, {'k': 'c'}]The lambda r: r["k"] is a tiny inline function: "given a row r, return r['k']." sorted calls it on every item and orders by the result.
Lambda — that's the anonymous-function syntax.
Right. lambda params: expr is a single-expression function with no name. Equivalent to:
def get_k(r):
return r["k"]
sorted(rows, key=get_k)Use a lambda when the function is one expression and used once. Define a regular function when the logic is bigger or you'll reuse it.
What other keys are common?
A few patterns you'll write often:
| Goal | key= |
|---|---|
| Sort strings by length | key=len |
| Sort dicts by a field | key=lambda r: r["field"] |
| Sort tuples by their second element | key=lambda t: t[1] |
| Sort case-insensitively | key=str.lower |
| Sort descending | add reverse=True |
sorted(iterable, key=fn) — sort by computed propertysorted([3, 1, 2]) # [1, 2, 3]
sorted([3, 1, 2], reverse=True) # [3, 2, 1]
sorted(["banana", "a", "cherry"], key=len)
# ['a', 'banana', 'cherry']sorted returns a new list — it doesn't modify the input. (list.sort() is the in-place version.)
key= is a functionThe value of key must be callable with one argument:
sorted(items, key=fn)
# Equivalent to: sort by fn(item) for each itemlambdaFor one-line keys, lambda saves you a def:
rows = [{"k": "b"}, {"k": "a"}, {"k": "c"}]
sorted(rows, key=lambda r: r["k"])
# [{'k': 'a'}, {'k': 'b'}, {'k': 'c'}]lambda PARAMS: EXPRESSION is an inline function. No return keyword — the expression is the return value.
# By length
sorted(words, key=len)
# Case-insensitive (string method as key)
sorted(words, key=str.lower)
# By dict field
sorted(rows, key=lambda r: r["name"])
# By tuple element
sorted(pairs, key=lambda t: t[1])
# Multiple keys (tuple of values)
sorted(rows, key=lambda r: (r["category"], r["name"]))
# Descending
sorted(rows, key=lambda r: r["date"], reverse=True)The tuple-key trick is powerful — sort by category first, then alphabetically within each category.
operator.itemgetter — a tidier alternativeFor dict and tuple field access, the standard library has a helper:
from operator import itemgetter
sorted(rows, key=itemgetter("name")) # by name
sorted(rows, key=itemgetter("category", "name")) # by category, then name
sorted(pairs, key=itemgetter(1)) # by tuple[1]Reads cleaner than the lambda equivalents and is slightly faster.
sorted is stableItems with equal keys keep their original relative order. So you can sort by primary key first, then later by secondary — it works:
result = sorted(rows, key=lambda r: r["name"]) # secondary
result = sorted(result, key=lambda r: r["category"]) # primary
# rows with same category keep alphabetical orderUseful when the sort logic comes in stages.
sorted vs list.sort| Behavior | When | |
|---|---|---|
sorted(xs) | returns new list, leaves input alone | functional style, small inputs, comprehensions |
xs.sort() | modifies in place, returns None | when you own the list and want to save memory |
Don't write xs = xs.sort() — xs becomes None.
sorted(numbers) works on a list of comparable values — numbers, strings. What about a list of dicts?
rows = [{"k": "b"}, {"k": "a"}, {"k": "c"}]
sorted(rows) # TypeError — Python doesn't know how to compare dictsRight, no natural ordering on dicts.
That's where the key= parameter comes in. You give sorted a function that takes one item and returns the value to sort by:
sorted(rows, key=lambda r: r["k"])
# [{'k': 'a'}, {'k': 'b'}, {'k': 'c'}]The lambda r: r["k"] is a tiny inline function: "given a row r, return r['k']." sorted calls it on every item and orders by the result.
Lambda — that's the anonymous-function syntax.
Right. lambda params: expr is a single-expression function with no name. Equivalent to:
def get_k(r):
return r["k"]
sorted(rows, key=get_k)Use a lambda when the function is one expression and used once. Define a regular function when the logic is bigger or you'll reuse it.
What other keys are common?
A few patterns you'll write often:
| Goal | key= |
|---|---|
| Sort strings by length | key=len |
| Sort dicts by a field | key=lambda r: r["field"] |
| Sort tuples by their second element | key=lambda t: t[1] |
| Sort case-insensitively | key=str.lower |
| Sort descending | add reverse=True |
sorted(iterable, key=fn) — sort by computed propertysorted([3, 1, 2]) # [1, 2, 3]
sorted([3, 1, 2], reverse=True) # [3, 2, 1]
sorted(["banana", "a", "cherry"], key=len)
# ['a', 'banana', 'cherry']sorted returns a new list — it doesn't modify the input. (list.sort() is the in-place version.)
key= is a functionThe value of key must be callable with one argument:
sorted(items, key=fn)
# Equivalent to: sort by fn(item) for each itemlambdaFor one-line keys, lambda saves you a def:
rows = [{"k": "b"}, {"k": "a"}, {"k": "c"}]
sorted(rows, key=lambda r: r["k"])
# [{'k': 'a'}, {'k': 'b'}, {'k': 'c'}]lambda PARAMS: EXPRESSION is an inline function. No return keyword — the expression is the return value.
# By length
sorted(words, key=len)
# Case-insensitive (string method as key)
sorted(words, key=str.lower)
# By dict field
sorted(rows, key=lambda r: r["name"])
# By tuple element
sorted(pairs, key=lambda t: t[1])
# Multiple keys (tuple of values)
sorted(rows, key=lambda r: (r["category"], r["name"]))
# Descending
sorted(rows, key=lambda r: r["date"], reverse=True)The tuple-key trick is powerful — sort by category first, then alphabetically within each category.
operator.itemgetter — a tidier alternativeFor dict and tuple field access, the standard library has a helper:
from operator import itemgetter
sorted(rows, key=itemgetter("name")) # by name
sorted(rows, key=itemgetter("category", "name")) # by category, then name
sorted(pairs, key=itemgetter(1)) # by tuple[1]Reads cleaner than the lambda equivalents and is slightly faster.
sorted is stableItems with equal keys keep their original relative order. So you can sort by primary key first, then later by secondary — it works:
result = sorted(rows, key=lambda r: r["name"]) # secondary
result = sorted(result, key=lambda r: r["category"]) # primary
# rows with same category keep alphabetical orderUseful when the sort logic comes in stages.
sorted vs list.sort| Behavior | When | |
|---|---|---|
sorted(xs) | returns new list, leaves input alone | functional style, small inputs, comprehensions |
xs.sort() | modifies in place, returns None | when you own the list and want to save memory |
Don't write xs = xs.sort() — xs becomes None.
Create a free account to get started. Paid plans unlock all tracks.