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 из стандартной библиотеки.

Если это не то, что вам нужно, я рекомендую вам пересмотреть функции сортировки, которые оставляют вас со списком кортежей. Какой результат вы хотели, если не упорядоченный список пар ключ-значение (кортежи)?