Python: как отсортировать словарь по значению и по ключу

Категория: Python · Язык: Python · Обновлено:

Чтобы отсортировать словарь в Python по значению, используйте dict(sorted(d.items(), key=lambda item: item[1])). По ключу достаточно dict(sorted(d.items())). Сам словарь на месте сортировать нельзя, функция sorted возвращает новый список пар.

Сортировка по значению и по ключу

Python
prices = {"хлеб": 45, "молоко": 90, "сыр": 450, "чай": 120}

by_value = dict(sorted(prices.items(), key=lambda item: item[1]))
print(by_value)  # {'хлеб': 45, 'молоко': 90, 'чай': 120, 'сыр': 450}

by_value_desc = dict(sorted(prices.items(), key=lambda item: item[1], reverse=True))
print(by_value_desc)  # {'сыр': 450, 'чай': 120, 'молоко': 90, 'хлеб': 45}

by_key = dict(sorted(prices.items()))
print(by_key)  # {'молоко': 90, 'сыр': 450, 'хлеб': 45, 'чай': 120}

Метод items() отдаёт пары (ключ, значение), а параметр key говорит, по какой части пары сортировать. Обычный словарь запоминает порядок вставки с Python 3.7, поэтому после dict(...) порядок сохраняется.

Только ключи или только значения

Python
print(sorted(prices, key=prices.get))  # ['хлеб', 'молоко', 'чай', 'сыр']
print(sorted(prices.values()))         # [45, 90, 120, 450]
print(max(prices, key=prices.get))     # сыр
print(min(prices, key=prices.get))     # хлеб

operator.itemgetter вместо lambda

Python
from operator import itemgetter

print(sorted(prices.items(), key=itemgetter(1))[0])  # ('хлеб', 45)

itemgetter(1) делает то же, что lambda item: item[1], и читается короче.

Сортировка по нескольким условиям

Чтобы упорядочить сначала по значению по убыванию, а при равенстве по ключу по возрастанию, верните из key кортеж. Минус перед числом меняет порядок только для этого поля:

Python
scores = {"Аня": 90, "Борис": 85, "Вера": 90, "Глеб": 85}

result = sorted(scores.items(), key=lambda item: (-item[1], item[0]))
print(result)  # [('Аня', 90), ('Вера', 90), ('Борис', 85), ('Глеб', 85)]

Словарь словарей

Python
users = {
    "u1": {"name": "Анна", "age": 31},
    "u2": {"name": "Игорь", "age": 25},
    "u3": {"name": "Ольга", "age": 28},
}

by_age = dict(sorted(users.items(), key=lambda item: item[1]["age"]))
print(list(by_age))  # ['u2', 'u3', 'u1']

Самые частые элементы

Для подсчёта и сортировки по частоте есть готовый класс Counter:

Python
from collections import Counter

print(Counter("abracadabra").most_common(3))  # [('a', 5), ('b', 2), ('r', 2)]

Частые вопросы

Можно ли отсортировать словарь без создания нового?

Нет, словарь не имеет собственной сортировки. Создайте отсортированную копию и присвойте её той же переменной: prices = dict(sorted(prices.items())).

Как сортировать по значению, если значения разных типов?

Приведите их к общему типу в key, например key=lambda item: str(item[1]). Сравнивать числа и строки напрямую Python не умеет и выдаст TypeError.

В какой версии Python словарь стал упорядоченным?

Порядок вставки гарантируется языком с Python 3.7. В 3.6 он сохранялся как особенность реализации CPython.