Python: как отсортировать словарь по значению и по ключу
Чтобы отсортировать словарь в Python по значению, используйте dict(sorted(d.items(), key=lambda item: item[1])). По ключу достаточно dict(sorted(d.items())). Сам словарь на месте сортировать нельзя, функция sorted возвращает новый список пар.
Сортировка по значению и по ключу
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(...) порядок сохраняется.
Только ключи или только значения
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
from operator import itemgetter
print(sorted(prices.items(), key=itemgetter(1))[0]) # ('хлеб', 45)itemgetter(1) делает то же, что lambda item: item[1], и читается короче.
Сортировка по нескольким условиям
Чтобы упорядочить сначала по значению по убыванию, а при равенстве по ключу по возрастанию, верните из key кортеж. Минус перед числом меняет порядок только для этого поля:
scores = {"Аня": 90, "Борис": 85, "Вера": 90, "Глеб": 85}
result = sorted(scores.items(), key=lambda item: (-item[1], item[0]))
print(result) # [('Аня', 90), ('Вера', 90), ('Борис', 85), ('Глеб', 85)]Словарь словарей
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:
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.