it-swarm.com.ru

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

У меня есть словарь значений, прочитанных из двух полей в базе данных: строковое поле и числовое поле. Строковое поле уникально, так что это ключ словаря.

Я могу сортировать по ключам, но как я могу сортировать по значениям?

Примечание: здесь я прочитал вопрос переполнения стека Как отсортировать список словарей по значению словаря? и Возможно, я мог бы изменить свой код, чтобы получить список словарей, но так как мне не нужен список словарей, я хотел бы знать, есть ли более простое решение для сортировки в порядке возрастания или убывания.

3428
Gern Blanston

Сортировать словарь невозможно, только чтобы получить представление отсортированного словаря. Словари по своей природе беспорядочные, но другие типы, такие как списки и кортежи, - нет. Таким образом, вам нужен упорядоченный тип данных для представления отсортированных значений, который будет списком - вероятно, списком кортежей.

Например,

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(1))

sorted_x будет списком кортежей, отсортированным по второму элементу в каждом кортеже. dict(sorted_x) == x.

А для желающих отсортировать по ключам вместо значений:

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(0))

В Python3, поскольку распаковка запрещена [1] мы можем использовать

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=lambda kv: kv[1])

Если вы хотите, чтобы вывод выводился как dict, вы можете использовать collections.OrderedDict :

import collections

sorted_dict = collections.OrderedDict(sorted_x)
4159
Devin Jeanpierre

Так же просто, как: sorted(dict1, key=dict1.get)

Ну, на самом деле можно сделать "сортировку по значениям словаря". Недавно мне пришлось сделать это в Code Golf (вопрос переполнения стека Code golf: Word частотная диаграмма). Сокращенно, проблема была в следующем виде: с учетом текста подсчитайте, как часто встречается каждое Слово, и отобразите список главных слов, отсортированных по убыванию частоты.

Если вы создаете словарь со словами в качестве ключей и числом вхождений каждого слова в качестве значения, то здесь это упрощается как:

from collections import defaultdict
d = defaultdict(int)
for w in text.split():
  d[w] += 1

затем вы можете получить список слов, упорядоченных по частоте использования, с помощью sorted(d, key=d.get) - сортировка перебирает ключи словаря, используя количество вхождений Word в качестве ключа сортировки.

for w in sorted(d, key=d.get, reverse=True):
  print w, d[w]

Я пишу это подробное объяснение, чтобы проиллюстрировать, что люди часто имеют в виду, "я могу легко отсортировать словарь по ключу, но как я могу отсортировать по значению" - и я думаю, что ОП пытался решить такую ​​проблему. И решение состоит в том, чтобы сделать вид списка ключей, основанный на значениях, как показано выше.

1094
Nas Banov

Вы можете использовать:

sorted(d.items(), key=lambda x: x[1])

Это позволит отсортировать словарь по значениям каждой записи в словаре от наименьшего к наибольшему.

Чтобы отсортировать его в порядке убывания, просто добавьте reverse=True:

sorted(d.items(), key=lambda x: x[1], reverse=True)
695
Mark

Дики не могут быть отсортированы, но вы можете создать отсортированный список из них.

Сортированный список значений dict:

sorted(d.values())

Список пар (ключ, значение), отсортированных по значению:

from operator import itemgetter
sorted(d.items(), key=itemgetter(1))
196
Roberto Bonvallet

В недавнем Python 2.7 у нас появился новый тип OrderedDict , который запоминает порядок, в котором элементы были добавлены.

>>> d = {"third": 3, "first": 1, "fourth": 4, "second": 2}

>>> for k, v in d.items():
...     print "%s: %s" % (k, v)
...
second: 2
fourth: 4
third: 3
first: 1

>>> d
{'second': 2, 'fourth': 4, 'third': 3, 'first': 1}

Чтобы создать новый упорядоченный словарь из оригинала, отсортировав по значениям:

>>> from collections import OrderedDict
>>> d_sorted_by_value = OrderedDict(sorted(d.items(), key=lambda x: x[1]))

OrderedDict ведет себя как обычный dict:

>>> for k, v in d_sorted_by_value.items():
...     print "%s: %s" % (k, v)
...
first: 1
second: 2
third: 3
fourth: 4

>>> d_sorted_by_value
OrderedDict([('first': 1), ('second': 2), ('third': 3), ('fourth': 4)])
151
mykhal

ОБНОВЛЕНИЕ: 5 ДЕКАБРЯ 2015 г. с использованием Python 3.5

Хотя я нашел полезный ответ, я также был удивлен, что он не был обновлен до ссылки OrderedDict из стандарта модуль библиотеки коллекций как жизнеспособная, современная альтернатива, предназначенная для решения именно этого типа проблем.

from operator import itemgetter
from collections import OrderedDict

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = OrderedDict(sorted(x.items(), key=itemgetter(1)))
# OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

Официальная OrderedDict документация также предлагает очень похожий пример, но с использованием лямбды для функции сортировки:

# regular unsorted dictionary
d = {'banana': 3, 'Apple':4, 'pear': 1, 'orange': 2}

# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
# OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('Apple', 4)])
94
arcseldon

Почти так же, как ответ Хэнка Гея :

sorted([(value,key) for (key,value) in mydict.items()])

Или слегка оптимизирован, как это было предложено Джоном Фухи:

sorted((value,key) for (key,value) in mydict.items())
74
user26294

Часто это может быть очень удобно для использования namedtuple, Например, у вас есть словарь "имя" в качестве ключей и "оценка" в качестве значений, и вы хотите отсортировать по "оценка":

import collections
Player = collections.namedtuple('Player', 'score name')
d = {'John':5, 'Alex':10, 'Richard': 7}

сортировка с наименьшим количеством баллов:

worst = sorted(Player(v,k) for (k,v) in d.items())

сортировка с наибольшим количеством баллов:

best = sorted([Player(v,k) for (k,v) in d.items()], reverse=True)

Теперь вы можете получить имя и счет, скажем, второго лучшего игрока (index = 1), очень Pythonly, как это:

player = best[1]
player.name
    'Richard'
player.score
    7
70
Remi

Начиная с Python 3.6 встроенный dict будет упорядочен

Хорошие новости, поэтому исходный вариант использования OP для отображения пар, извлеченных из базы данных с уникальными строковыми идентификаторами в качестве ключей и числовыми значениями в качестве значений во встроенном Python v3.6 + dict, теперь должен учитывать вставку порядок.

Если, скажем, результирующие выражения таблицы в два столбца из запроса к базе данных, как:

SELECT a_key, a_value FROM a_table ORDER BY a_value;

будет храниться в двух Python кортежах, k_seq и v_seq (выровненных по числовому индексу и, конечно же, с одинаковой длиной), затем:

k_seq = ('foo', 'bar', 'baz')
v_seq = (0, 1, 42)
ordered_map = dict(Zip(k_seq, v_seq))

Разрешить вывод позже как:

for k, v in ordered_map.items():
    print(k, v)

уступая в этом случае (для нового Python 3.6+ встроенного dict!):

foo 0
bar 1
baz 42

в том же порядке на значение v.

Где при установке на моем компьютере Python 3.5 он в настоящее время выдает:

bar 1
foo 0
baz 42

Подробности:

Как было предложено в 2012 году Рэймондом Хеттингером (см. Почту на python-dev с темой "Более компактные словари с более быстрой итерацией" ), а теперь (в 2016 году) объявлено в письме Виктора Стиннера на почту python-dev. with subject "Python 3.6 dict становится компактным и получает приватную версию; ключевые слова становятся упорядоченными" из-за исправления/реализации проблемы 27350 "Compact and order dict" in Python 3.6 теперь мы сможем использовать встроенный dict для поддержания порядка вставки !!

Надеемся, что это приведет к тонкому слою реализации OrderedDict в качестве первого шага. Как указывало @ JimFasarakis-Hilliard, некоторые видят варианты использования для типа OrderedDict и в будущем. Я думаю, что сообщество Python будет тщательно проверять, выдержит ли это испытание временем, и какие будут следующие шаги.

Время переосмыслить наши привычки кодирования, чтобы не упустить возможности, открываемые стабильным упорядочением:

  • Ключевое слово аргументы и
  • промежуточное хранение

Первый, потому что в некоторых случаях он облегчает выполнение функций и методов.

Второе, так как оно поощряет более простое использование dicts в качестве промежуточного хранилища в конвейерах обработки.

Рэймонд Хеттингер любезно предоставил документацию, объясняющую " Технология позади Python 3.6 Словари =" - из его презентации в Сан-Франциско Python Meetup Group 2016-DEC-08.

И, может быть, довольно много страниц с вопросами и ответами в Stack Overflow получат варианты этой информации, и многие высококачественные ответы также потребуют обновления для каждой версии.

Предостережение Emptor (но также см. Ниже обновление 2017-12-15):

Как справедливо отмечает @ajcr: "Сохраняющий порядок аспект этой новой реализации считается деталью реализации и на нее не следует полагаться". (из whatsnew36 ) не придирки, , но цитата была вырезана немного пессимистично ;-). Это продолжается как "(это может измениться в будущем, но желательно иметь эту новую реализацию dict в языке в течение нескольких выпусков, прежде чем изменять спецификацию языка, чтобы предписывать семантику сохранения порядка для всех текущих и будущих Python реализации; это также помогает сохранить обратную совместимость со старыми версиями языка, где все еще действует случайный порядок итераций, например Python 3.5). "

Как и в некоторых человеческих языках (например, немецком), использование определяет язык, и завещание было объявлено ... in whatsnew36 .

Обновление 2017-12-15:

В письмо в список python-dev Гвидо ван Россум объявил:

Сделай это так. "Dict сохраняет порядок вставки" - это решение. Спасибо!

Таким образом, побочный эффект CPython версии 3.6 от порядка вставки dict теперь становится частью языковой спецификации (а не только детали реализации). В этой почтовой ветке также появились некоторые отличительные цели дизайна для collections.OrderedDict, как напомнил Рэймонд Хеттингер во время обсуждения.

67
Dilettant

Данный словарь

e = {1:39, 4:34, 7:110, 2:87}

Сортировка

sred = sorted(e.items(), key=lambda value: value[1])

Результат

[(4, 34), (1, 39), (2, 87), (7, 110)]

Вы можете использовать лямбда-функцию, чтобы отсортировать вещи по значению и сохранить их обработанными внутри переменной, в этом случае sred с e исходным словарем.

Надеюсь, это поможет!

44
bishop

У меня была такая же проблема, и я решил ее так:

WantedOutput = sorted(MyDict, key=lambda x : MyDict[x]) 

(Люди, которые отвечают "Невозможно отсортировать диктовку", не читали вопрос! На самом деле, "Я могу сортировать по ключам, но как я могу сортировать по значениям?" Ясно означает, что ему нужен список ключи отсортированы по значению их значений.)

Обратите внимание, что порядок не определен (ключи с одинаковыми значениями будут в произвольном порядке в списке вывода).

40
jimifiki

В Python 2.7 просто выполните:

from collections import OrderedDict
# regular unsorted dictionary
d = {'banana': 3, 'Apple':4, 'pear': 1, 'orange': 2}

# dictionary sorted by key
OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('Apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('Apple', 4)])

скопируйте и вставьте из: http://docs.python.org/dev/library/collections.html#ordereddict-examples-and-recipes

Наслаждаться ;-)

34
sweetdream

Технически словари не являются последовательностями, и поэтому не могут быть отсортированы. Вы можете сделать что-то вроде

sorted(a_dictionary.values())

при условии, что производительность не так уж и велика.

26
Hank Gay

Это код:

import operator
Origin_list = [
    {"name": "foo", "rank": 0, "rofl": 20000},
    {"name": "Silly", "rank": 15, "rofl": 1000},
    {"name": "Baa", "rank": 300, "rofl": 20},
    {"name": "Zoo", "rank": 10, "rofl": 200},
    {"name": "Penguin", "rank": -1, "rofl": 10000}
]
print ">> Original >>"
for foo in Origin_list:
    print foo

print "\n>> Rofl sort >>"
for foo in sorted(Origin_list, key=operator.itemgetter("rofl")):
    print foo

print "\n>> Rank sort >>"
for foo in sorted(Origin_list, key=operator.itemgetter("rank")):
    print foo

Вот результаты:

Original

{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}

Rofl

{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}

ранг

{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}
25
PedroMorgan

Если значения являются числовыми, вы также можете использовать Counter from collection .

from collections import Counter

x = {'hello': 1, 'python': 5, 'world': 3}
c = Counter(x)
print(c.most_common())

>> [('python', 5), ('world', 3), ('hello', 1)]    
24
Ivan Sas

Попробуйте следующий подход. Давайте определим словарь mydict со следующими данными:

mydict = {'carl':40,
          'alan':2,
          'bob':1,
          'danny':3}

Если кто-то хочет отсортировать словарь по ключам, можно сделать что-то вроде:

for key in sorted(mydict.iterkeys()):
    print "%s: %s" % (key, mydict[key])

Это должно вернуть следующий вывод:

alan: 2
bob: 1
carl: 40
danny: 3

С другой стороны, если кто-то хочет отсортировать словарь по значению (как это задается в вопросе), можно сделать следующее:

for key, value in sorted(mydict.iteritems(), key=lambda (k,v): (v,k)):
    print "%s: %s" % (key, value)

Результат этой команды (сортировка словаря по значению) должен вернуть следующее:

bob: 1
alan: 2
danny: 3
carl: 40
23
Nathaniel Payne

Вы можете создать "инвертированный индекс", также

from collections import defaultdict
inverse= defaultdict( list )
for k, v in originalDict.items():
    inverse[v].append( k )

Теперь ваш обратный имеет значения; у каждого значения есть список применимых ключей.

for k in sorted(inverse):
    print k, inverse[k]
21
S.Lott

Вы можете использовать collection.Counter . Обратите внимание, что это будет работать как для числовых, так и для нечисловых значений.

>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> from collections import Counter
>>> #To sort in reverse order
>>> Counter(x).most_common()
[(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
>>> #To sort in ascending order
>>> Counter(x).most_common()[::-1]
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
>>> #To get a dictionary sorted by values
>>> from collections import OrderedDict
>>> OrderedDict(Counter(x).most_common()[::-1])
OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])
20
Abhijit

Это возвращает список пар ключ-значение в словаре, отсортированных по значению от самого высокого до самого низкого:

sorted(d.items(), key=lambda x: x[1], reverse=True)

Для словаря, отсортированного по ключу, используйте следующее:

sorted(d.items(), reverse=True)

Возвращаемым является список кортежей, потому что сами словари не могут быть отсортированы.

Это может быть как распечатано, так и отправлено в дальнейшие вычисления.

16
Zags

Начиная с Python 3.6, объекты dict теперь упорядочены по порядку вставки. Это официально в спецификации Python 3.7.

>>> words = {"python": 2, "blah": 4, "alice": 3}
>>> dict(sorted(words.items(), key=lambda x: x[1]))
{'python': 2, 'alice': 3, 'blah': 4}

До этого вам приходилось использовать OrderedDict.

документация по Python 3.7 говорит:

Изменено в версии 3.7: Порядок словаря гарантированно является порядком вставки. Такое поведение было деталью реализации CPython от 3.6.

16
Maxime Chéramy

Вы можете использовать пропустить dict , который является словарем, который постоянно сортируется по значению.

>>> data = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
>>> SkipDict(data)
{0: 0.0, 2: 1.0, 1: 2.0, 4: 3.0, 3: 4.0}

Если вы используете keys(), values() или items(), вы будете выполнять итерацию в отсортированном порядке по значению.

Это реализовано с использованием пропустить список структура данных.

15
malthe
from Django.utils.datastructures import SortedDict

def sortedDictByKey(self,data):
    """Sorted dictionary order by key"""
    sortedDict = SortedDict()
    if data:
        if isinstance(data, dict):
            sortedKey = sorted(data.keys())
            for k in sortedKey:
                sortedDict[k] = data[k]
    return sortedDict
13
Argun

Вы также можете использовать пользовательскую функцию, которую можно передать клавише.

def dict_val(x):
    return x[1]
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=dict_val)
12
Vishwanath Rawat

Как указал Дилетант , Python 3.6 теперь сохранит порядок ! Я думал, что у меня будет функция, которую я написал, которая упрощает сортировку итерируемого (Tuple, list, dict). В последнем случае вы можете сортировать либо по ключам, либо по значениям, и это может учитывать числовое сравнение. Только для> = 3.6!

Когда вы пытаетесь использовать сортировку по итерируемой, которая содержит, например, Строки, а также int, sorted () потерпит неудачу. Конечно, вы можете форсировать сравнение строк с помощью str (). Однако в некоторых случаях вы хотите выполнить фактическое числовое сравнение, где 12 меньше, чем 20 (что не имеет место при сравнении строк). Итак, я придумал следующее. Когда вы хотите явное числовое сравнение, вы можете использовать флаг num_as_num, который попытается выполнить явную числовую сортировку, пытаясь преобразовать все значения в числа с плавающей точкой. Если это удастся, он выполнит числовую сортировку, иначе он прибегнет к сравнению строк.

Комментарии для улучшения или Push-запросы Добро пожаловать.

def sort_iterable(iterable, sort_on=None, reverse=False, num_as_num=False):
    def _sort(i):
      # sort by 0 = keys, 1 values, None for lists and tuples
      try:
        if num_as_num:
          if i is None:
            _sorted = sorted(iterable, key=lambda v: float(v), reverse=reverse)
          else:
            _sorted = dict(sorted(iterable.items(), key=lambda v: float(v[i]), reverse=reverse))
        else:
          raise TypeError
      except (TypeError, ValueError):
        if i is None:
          _sorted = sorted(iterable, key=lambda v: str(v), reverse=reverse)
        else:
          _sorted = dict(sorted(iterable.items(), key=lambda v: str(v[i]), reverse=reverse))

      return _sorted

    if isinstance(iterable, list):
      sorted_list = _sort(None)
      return sorted_list
    Elif isinstance(iterable, Tuple):
      sorted_list = Tuple(_sort(None))
      return sorted_list
    Elif isinstance(iterable, dict):
      if sort_on == 'keys':
        sorted_dict = _sort(0)
        return sorted_dict
      Elif sort_on == 'values':
        sorted_dict = _sort(1)
        return sorted_dict
      Elif sort_on is not None:
        raise ValueError(f"Unexpected value {sort_on} for sort_on. When sorting a dict, use key or values")
    else:
      raise TypeError(f"Unexpected type {type(iterable)} for iterable. Expected a list, Tuple, or dict")
10
Bram Vanroy

Вот решение, использующее Zip on d.values() И d.keys() . Несколько строк по этой ссылке (в объектах словаря):

Это позволяет создавать пары (значение, ключ) с помощью Zip (): pair = Zip (d.values ​​(), d.keys ()).

Таким образом, мы можем сделать следующее:

d = {'key1': 874.7, 'key2': 5, 'key3': 8.1}

d_sorted = sorted(Zip(d.values(), d.keys()))

print d_sorted 
# prints: [(5, 'key2'), (8.1, 'key3'), (874.7, 'key1')]
9
Scott

Используйте ValueSortedDict из dicts :

from dicts.sorteddict import ValueSortedDict
d = {1: 2, 3: 4, 4:3, 2:1, 0:0}
sorted_dict = ValueSortedDict(d)
print sorted_dict.items() 

[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
7
ponty

Конечно, помните, вам нужно использовать OrderedDict, потому что обычные словари Python не сохраняют первоначальный порядок.

from collections import OrderedDict
a = OrderedDict(sorted(originalDict.items(), key=lambda x: x[1]))

Если у вас нет Python 2.7 или выше, лучшее, что вы можете сделать, - это перебирать значения в функции генератора. (Существует OrderedDict для 2.4 и 2.6 здесь , но

а) я не знаю, насколько хорошо это работает

а также

б) Вы должны скачать и установить его, конечно. Если у вас нет доступа с правами администратора, то, боюсь, опция отключена.)


def gen(originalDict):
    for x, y in sorted(Zip(originalDict.keys(), originalDict.values()), key=lambda z: z[1]):
        yield (x, y)
    #Yields as a Tuple with (key, value). You can iterate with conditional clauses to get what you want. 

for bleh, meh in gen(myDict):
    if bleh == "foo":
        print(myDict[bleh])

Вы также можете распечатать каждое значение

for bleh, meh in gen(myDict):
    print(bleh, meh)

Пожалуйста, не забудьте удалить скобки после печати, если не используете Python 3.0 или выше

6
ytpillai

Итерируйте через dict и сортируйте его по значениям в порядке убывания:

$ python --version
Python 3.2.2

$ cat sort_dict_by_val_desc.py 
dictionary = dict(siis = 1, sana = 2, joka = 3, tuli = 4, aina = 5)
for Word in sorted(dictionary, key=dictionary.get, reverse=True):
  print(Word, dictionary[Word])

$ python sort_dict_by_val_desc.py 
aina 5
tuli 4
joka 3
sana 2
siis 1
6
juhoh

Если ваши значения являются целыми числами и вы используете Python 2.7 или новее, вы можете использовать collections.Counter вместо dict. Метод most_common выдаст вам все элементы, отсортированные по значению.

6
Petr Viktorin

Я придумал это,

import operator    
x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
sorted_x = {k[0]:k[1] for k in sorted(x.items(), key=operator.itemgetter(1))}

Для Python 3.x: x.items() заменяя iteritems().

>>> sorted_x
{0: 0, 1: 2, 2: 1, 3: 4, 4: 3}

Или попробуйте с collections.OrderedDict!

x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
from collections import OrderedDict

od1 = OrderedDict(sorted(x.items(), key=lambda t: t[1]))
6
kiriloff

Вы можете использовать отсортированную функцию Python

sorted(iterable[, cmp[, key[, reverse]]])

Таким образом, вы можете использовать:

sorted(dictionary.items(),key = lambda x :x[1])

Посетите эту ссылку для получения дополнительной информации о отсортированной функции: https://docs.python.org/2/library/functions.html#sorted

6
kkk

Это работает в 3.1.x:

import operator
slovar_sorted=sorted(slovar.items(), key=operator.itemgetter(1), reverse=True)
print(slovar_sorted)
5
iFail

Ради полноты я выкладываю решение, используя heapq . Обратите внимание, что этот метод будет работать как для числовых, так и для нечисловых значений.

>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> x_items = x.items()
>>> heapq.heapify(x_items)
>>> #To sort in reverse order
>>> heapq.nlargest(len(x_items),x_items, operator.itemgetter(1))
[(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
>>> #To sort in ascending order
>>> heapq.nsmallest(len(x_items),x_items, operator.itemgetter(1))
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
5
Abhijit

Только что выучил соответствующий навык у Python for Everybody .

Вы можете использовать временный список для сортировки словаря:

#Assume dictionary to be:
d = {'Apple': 500.1, 'banana': 1500.2, 'orange': 1.0, 'pineapple': 789.0}

# create a temporary list
tmp = []

# iterate through the dictionary and append each Tuple into the temporary list 
for key, value in d.items():
    tmptuple = (value, key)
    tmp.append(tmptuple)

# sort the list in ascending order
tmp = sorted(tmp)

print (tmp)

Если вы хотите отсортировать список в порядке убывания, просто измените исходную строку сортировки на:

tmp = sorted(tmp, reverse=True)

Используя понимание списка, один вкладыш будет:

#Assuming the dictionary looks like
d = {'Apple': 500.1, 'banana': 1500.2, 'orange': 1.0, 'pineapple': 789.0}
#One liner for sorting in ascending order
print (sorted([(v, k) for k, v in d.items()]))
#One liner for sorting in descending order
print (sorted([(v, k) for k, v in d.items()], reverse=True))

Пример вывода:

#Asending order
[(1.0, 'orange'), (500.1, 'Apple'), (789.0, 'pineapple'), (1500.2, 'banana')]
#Descending order
[(1500.2, 'banana'), (789.0, 'pineapple'), (500.1, 'Apple'), (1.0, 'orange')]
5
mcgag
months = {"January": 31, "February": 28, "March": 31, "April": 30, "May": 31,
          "June": 30, "July": 31, "August": 31, "September": 30, "October": 31,
          "November": 30, "December": 31}

def mykey(t):
    """ Customize your sorting logic using this function.  The parameter to
    this function is a Tuple.  Comment/uncomment the return statements to test
    different logics.
    """
    return t[1]              # sort by number of days in the month
    #return t[1], t[0]       # sort by number of days, then by month name
    #return len(t[0])        # sort by length of month name
    #return t[0][-1]         # sort by last character of month name


# Since a dictionary can't be sorted by value, what you can do is to convert
# it into a list of tuples with Tuple length 2.
# You can then do custom sorts by passing your own function to sorted().
months_as_list = sorted(months.items(), key=mykey, reverse=False)

for month in months_as_list:
    print month
3
lessthanl0l

Из-за требований сохранить обратную совместимость со старыми версиями Python Я думаю, что решение OrderedDict очень неразумно. Вы хотите что-то, что работает с Python 2.7 и более ранними версиями.

Но решение коллекций, упомянутое в другом ответе, абсолютно превосходно, потому что вы переобучаете связь между ключом и значением, что в случае словарей чрезвычайно важно.

Я не согласен с выбором номер один, представленным в другом ответе, потому что он выбрасывает ключи.

Я использовал решение, упомянутое выше (код, показанный ниже), и сохранил доступ к ключам и значениям, и в моем случае упорядочение было по значениям, но важным было упорядочение ключей после упорядочения значений.

from collections import Counter

x = {'hello':1, 'python':5, 'world':3}
c=Counter(x)
print c.most_common()


>> [('python', 5), ('world', 3), ('hello', 1)]
3
Eamonn Kenny

Томас Кокелер объясняет это очень элегантно. Мне нравится упомянуть краткую заметку о его статье.

Давайте рассмотрим следующий словарь.

d = {"Pierre": 42, "Anne": 33, "Zoe": 24}

Для сортировки на основе значений представлены следующие подходы.

sorted функция и operator модуль

import operator
sorted_d = sorted(d.items(), key=operator.itemgetter(1))


sorted функция и lambda функция

sorted_d = sorted(d.items(), key=lambda x: x[1])


sorted функцию и вернуть упорядоченный словарь

В предыдущих методах возвращаемые объекты являются списком кортежей. Так что у нас больше нет словаря. Мы можем использовать OrderedDict, если захотим.

from collections import OrderedDict
sorted_d  = OrderedDict(sorted(d.items(), key=lambda x: x[1]))


sorted функция и понимание списка

sorted_d = sorted((value, key) for (key,value) in d.items())

Тем не менее, Он также сделал быстрый тест вышеупомянутой процедуры.

3
iNet

Помимо использования встроенного модуля и т.д., Я пытаюсь решить его вручную ..... сначала я создал функцию, задачей которой является возвращение минимального значения каждому элементу dict:

def returnminDict(_dct):
    dict_items = _dct.items()
    list_items = list(dict_items)
    init_items = list_items[0]
    for i in range(len(list_items)):
        if list_items[i][1] > init_items[1]:
           continue
        else:
           init_items = list_items[i]
    return init_items

Second, теперь у нас есть функция, которая возвращает элемент с минимальным значением, затем я делаю новый dict, затем зацикливаю его:

def SelectDictSort(_dct):
    new_dict = {}
    while _dct:
        mindict = returnminDict(_dct)
        new_dict.update(dict((mindict,)))
        _dct.pop(mindict[0])
    return new_dict

я пытаюсь это SelectDictSort({2: 5, 5: 1, 4: 3, 1: 1, 0: 1, 9: 2, 8: 2}) вернется:

{0: 1, 1: 1, 5: 1, 8: 2, 9: 2, 4: 3, 2: 5}

Хммм ... я не знаю, что правильно, но это то, что я пытался ....

(обновлен код с retrun new_dct до return new_dict)

1
Wira Bhakti

Использование Python 3.2:

x = {"b":4, "a":3, "c":1}
for i in sorted(x.values()):
    print(list(x.keys())[list(x.values()).index(i)])
0
raton
>>> import collections
>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> sorted_x = collections.OrderedDict(sorted(x.items(), key=lambda t:t[1]))
>>> OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

OrderedDict является подклассом dict

0
liuzhijun

Этот метод не будет использовать лямбду и хорошо работает на Python 3.6:

 # sort dictionary by value
d = {'a1': 'fsdfds', 'g5': 'aa3432ff', 'ca':'zz23432'}
def getkeybyvalue(d,i):
    for k, v in d.items():
        if v == i:
            return (k)

sortvaluelist = sorted(d.values())

# In >> Python 3.6+ << the INSERTION-ORDER of a dict is preserved. That is,
# when creating a NEW dictionary and filling it 'in sorted order',
# that order will be maintained.
sortresult ={}
for i1 in sortvaluelist:   
    key = getkeybyvalue(d,i1)
    sortresult[key] = i1
print ('=====sort by value=====')
print (sortresult)
print ('=======================')
0
xiyurui