Python 3 сортирует по его значениям
Единственные методы, которые я нашел, работают для python2 или возвращают только список кортежей.
Можно ли сортировать словарь, например {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
, по его значениям?
Порядок сортированного словаря, который я хочу достичь, от самого большого до самого маленького. Я хочу, чтобы результаты выглядели так:
bb 4
aa 3
cc 2
dd 1
И после сортировки я хочу сохранить его в текстовый файл.
Ответы
Ответ 1
itemgetter
(см. другие ответы) является (как я знаю) более эффективным для больших словарей, но для обычного случая, я считаю, что d.get
. И это не требует дополнительного import
.
>>> d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
>>> s = [(k, d[k]) for k in sorted(d, key=d.get, reverse=True)]
>>> for k, v in s:
... k, v
...
('bb', 4)
('aa', 3)
('cc', 2)
('dd', 1)
Обратите внимание, что в качестве альтернативы вы можете установить d.__getitem__
как key
функцию, которая может обеспечить небольшое повышение производительности над d.get
.
Ответ 2
from collections import OrderedDict
from operator import itemgetter
d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
print(OrderedDict(sorted(d.items(), key = itemgetter(1), reverse = True)))
печать
OrderedDict([('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)])
Хотя из вашего последнего предложения кажется, что список кортежей будет работать нормально, например
from operator import itemgetter
d = {"aa": 3, "bb": 4, "cc": 2, "dd": 1}
for key, value in sorted(d.items(), key = itemgetter(1), reverse = True):
print(key, value)
который печатает
bb 4
aa 3
cc 2
dd 1
Ответ 3
Для сортировки словаря мы могли бы использовать операторский модуль. Вот документация модуля оператора.
import operator #Importing operator module
dc = {"aa": 3, "bb": 4, "cc": 2, "dd": 1} #Dictionary to be sorted
dc_sort = sorted(dc.items(),key = operator.itemgetter(1),reverse = True)
print dc_sort
Последовательность вывода будет отсортированным:
[('bb', 4), ('aa', 3), ('cc', 2), ('dd', 1)]
Если мы хотим сортировать по отношению к ключам, мы можем использовать
dc_sort = sorted(dc.items(),key = operator.itemgetter(0),reverse = True)
Последовательность вывода будет:
[('dd', 1), ('cc', 2), ('bb', 4), ('aa', 3)]
Ответ 4
Более простой (и ~ 10% быстрее) способ - использовать лямбда-выражение
d = {'aa': 3, 'bb': 4, 'cc': 2, 'dd': 1}
s = sorted(d.items(), key=lambda x: x[1], reverse=True)
for k, v in s:
print(k, v)
Задержки
%%timeit
на CPython 3.7 с print(k, v)
заменяющим pass
чтобы не допустить ввода-вывода в картину.
Принятый ответ с помощью d.get():
1.19 µs ± 16.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Лямбда-выражение:
1.07 µs ± 10.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Ответ 5
Вы можете сортировать по значениям в обратном порядке (от наибольшего к наименьшему), используя словарь:
{k: d[k] for k in sorted(d, key=d.get, reverse=True)}
# {'b': 4, 'a': 3, 'c': 2, 'd': 1}
Если вы хотите отсортировать по значениям в порядке возрастания (от наименьшего к наибольшему)
{k: d[k] for k in sorted(d, key=d.get)}
# {'d': 1, 'c': 2, 'a': 3, 'b': 4}
Если вы хотите отсортировать по ключам в порядке возрастания
{k: d[k] for k in sorted(d)}
# {'a': 3, 'b': 4, 'c': 2, 'd': 1}
Это работает на CPython 3. 6+ и любой реализации Python 3. 7+, потому что словари сохраняют порядок вставки.
Ответ 6
Чтобы отсортировать словарь и сохранить его в качестве словаря впоследствии, вы можете использовать OrderedDict из стандартной библиотеки.
Если это не то, что вам нужно, я рекомендую вам пересмотреть функции сортировки, которые оставляют вас со списком кортежей. Какой результат вы хотели, если не упорядоченный список пар ключ-значение (кортежи)?