Коротко
В Python словари не сортируются на месте — порядок ключей в dict фиксируется по вставке. Поэтому «отсортировать словарь по значению» = получить новый словарь (или список пар) в нужном порядке.
Способ 1. Новый словарь (Python 3.7+)
d = {'a': 3, 'b': 1, 'c': 2}
# по возрастанию значения
sorted_d = dict(sorted(d.items(), key=lambda x: x[1]))
print(sorted_d) # {'b': 1, 'c': 2, 'a': 3}
# по убыванию
sorted_d = dict(sorted(d.items(), key=lambda x: x[1], reverse=True))
print(sorted_d) # {'a': 3, 'c': 2, 'b': 1}
Тут d.items() даёт пары (ключ, значение), а lambda x: x[1] говорит: сортируй по второму элементу пары (значению). x[0] — это ключ.
Способ 2. Через operator.itemgetter (чуть быстрее и короче)
from operator import itemgetter
sorted_d = dict(sorted(d.items(), key=itemgetter(1)))
Почему у вас получался список кортежей
Потому что sorted(d.items(), ...) всегда возвращает список кортежей — это нормально. Просто оберните его в dict(...), как выше, и получите словарь.
Если цикл ломался — скорее всего вы делали так:
for k, v in sorted(d.items(), key=lambda x: x[1]): # тут всё ок
...
А вот так — уже ошибка, потому что итерируетесь по кортежу (ключ, значение):
for k in sorted(d.items(), key=lambda x: x[1]): # k — это кортеж, а не ключ
Если значения одинаковые
Сортировка по значению нестабильна по ключу — добавьте второй критерий:
sorted_d = dict(sorted(d.items(), key=lambda x: (x[1], x[0])))
Сначала по значению, при равенстве — по ключу.
Если нужен только топ-N
top3 = sorted(d.items(), key=lambda x: x[1], reverse=True)[:3]
Тут словарь не нужен — список пар удобнее.
Ответить на вопрос