This started as a short Italian post in 2009. Python has changed a lot since then. The biggest change for this topic: since Python 3.7, a dict keeps its keys in insertion order. A sorted dict is now one line away.

The example data is the same as in 2009:

python
d = {"bart": "marge", "maggie": "homer", "milhouse": "nelson", "lisa": "skinner"}

By key

sorted() on a dict iterates over its keys:

python
for k in sorted(d):
    print(f"{k}: {d[k]}")

# bart: marge
# lisa: skinner
# maggie: homer
# milhouse: nelson

To get a dict back instead of a loop, sort the items and build a new dict from them:

python
by_key = dict(sorted(d.items()))
# {'bart': 'marge', 'lisa': 'skinner', 'maggie': 'homer', 'milhouse': 'nelson'}

By value

Pass a key function that picks the second element of each (key, value) pair. operator.itemgetter does exactly that:

python
from operator import itemgetter

by_value = dict(sorted(d.items(), key=itemgetter(1)))
# {'maggie': 'homer', 'bart': 'marge', 'milhouse': 'nelson', 'lisa': 'skinner'}

key=lambda kv: kv[1] works too; it’s what I used in 2009. I find itemgetter(1) easier to read once you know it.

For descending order, add reverse=True:

python
dict(sorted(d.items(), key=itemgetter(1), reverse=True))
# {'lisa': 'skinner', 'milhouse': 'nelson', 'bart': 'marge', 'maggie': 'homer'}

When the values are counts

If you’re sorting by value to find the most frequent items, use collections.Counter:

python
from collections import Counter

words = Counter("the cat and the hat and the bat".split())
words.most_common(2)
# [('the', 3), ('and', 2)]

Ordered is not sorted

A dict remembers insertion order, but it doesn’t stay sorted: a key you add later goes to the end. If you need a mapping that stays sorted as you insert, use SortedDict from sortedcontainers.