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:
d = {"bart": "marge", "maggie": "homer", "milhouse": "nelson", "lisa": "skinner"}By key
sorted() on a dict iterates over its keys:
for k in sorted(d):
print(f"{k}: {d[k]}")
# bart: marge
# lisa: skinner
# maggie: homer
# milhouse: nelsonTo get a dict back instead of a loop, sort the items and build a new dict from them:
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:
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:
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:
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.