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

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

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

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

5.03.2009 00:49:05
Структура данных словаря не имеет собственного порядка. Вы можете выполнить итерацию, но нет ничего, что могло бы гарантировать, что итерация будет следовать какому-либо определенному порядку. Это сделано специально, поэтому лучше всего использовать другую структуру данных для представления.
Daishiman 5.07.2010 02:08:19
«sorted ()» может работать со словарями (и возвращает список отсортированных ключей), поэтому я думаю, что он знает об этом. Не зная его программы, абсурдно говорить кому-то, что они используют неправильную структуру данных. Если быстрый поиск - это то, что вам нужно в 90% случаев, то, скорее всего, вам нужен диктат.
bobpaul 15.02.2013 19:04:51
Все три вывода (ключи, значения, оба) для словарей сортировки представлены здесь в ясном и лаконичном стиле: stackoverflow.com/questions/16772071/sort-dict-by-value-python
JStrahl 7.03.2016 10:14:49
@Daishiman Базовый класс не может быть упорядочен, но, конечно, OrderedDict .
Taylor Edmiston 9.09.2017 01:10:20
В Python 3.6+ словари сохраняют порядок вставки. Это, конечно, не то же самое, что возможность сортировки их по значению, но, с другой стороны, уже нельзя утверждать, что «структура данных словаря не имеет собственного порядка».
Konrad Kocik 31.12.2018 13:30:40
30 ОТВЕТОВ
РЕШЕНИЕ

Python 3.6+

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
{k: v for k, v in sorted(x.items(), key=lambda item: item[1])}
{0: 0, 2: 1, 1: 2, 4: 3, 3: 4}

Старый Питон

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

Например,

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])

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

import collections

sorted_dict = collections.OrderedDict(sorted_x)
4835
9.12.2019 06:56:42
время для сортировки различных словарей по схемам значений: writeonly.wordpress.com/2008/08/30/…
Gregg Lind 14.03.2009 17:55:50
sorted_x.reverse()даст вам по убыванию (по второму элементу кортежа)
saidimu apale 3.05.2010 05:24:35
saidimu: Поскольку мы уже используем sorted(), гораздо эффективнее передать reverse=Trueаргумент.
rmh 5.07.2010 02:59:42
В Python3 я использовал лямбда: sorted(d.items(), key=lambda x: x[1]). Будет ли это работать в Python 2.x?
Keyo 15.02.2011 15:05:11
OrderedDict добавлен в коллекции в 2.7. Пример сортировки показан по адресу: docs.python.org/library/…
monkut 24.04.2011 06:31:11

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

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

sorted(d.values())

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

from operator import itemgetter
sorted(d.items(), key=itemgetter(1))
231
16.09.2014 17:26:10
В каком порядке размещены ключи с одинаковым значением? Сначала я отсортировал список по ключам, а затем по значениям, но порядок ключей с одинаковым значением не сохраняется.
SabreWolfy 18.06.2012 10:04:04
Dicts теперь можно сортировать, начиная с CPython 3.6 и всех других реализаций Python, начиная с 3.7
Boris 24.04.2020 19:38:07

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

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

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

sorted((value,key) for (key,value) in mydict.items())
85
12.03.2019 05:18:46
... и как и в случае с ответом Хэнка Гея, вам не нужны квадратные скобки. sorted () с радостью примет любую итерацию, например выражение генератора.
John Fouhy 5.03.2009 01:45:48
Возможно, вам все еще придется поменять элементы кортежа (значение, ключ), чтобы получить (ключ, значение). Затем необходимо другое понимание списка. [(key, value) for (value, key) in sorted_list_of_tuples]
saidimu apale 3.05.2010 05:22:24
нет, лучше оставить квадратные скобки, потому sortedчто в любом случае придется пересоздать список, и перестроение из gencomp будет быстрее. Хорошо для игры в гольф, плохо для скорости. Держи уродливую ([])версию.
Jean-François Fabre♦ 7.12.2017 21:21:54

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

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]
20
5.03.2009 01:52:18

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

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

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

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

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

Входные данные:

d = {'one':1,'three':3,'five':5,'two':2,'four':4}
a = sorted(d.items(), key=lambda x: x[1])    
print(a)

Вывод:

[('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]
844
10.01.2020 09:43:23
Из того, что я видел ( docs.python.org/2/library/… ), есть класс с именем OrderedDict, который можно сортировать и сохранять порядок, оставаясь в то же время словарем. Из примеров кода вы можете использовать лямбду для сортировки, но я лично не пробовал: P
UsAndRufus 20.02.2013 10:38:11
Я бы предпочел key=lambda (k, v): vлично
Claudiu 9.04.2015 23:08:56
@Claudiu Мне также нравится этот (k, v)синтаксис, но он недоступен в Python 3, где была удалена распаковка параметров кортежа .
Bob Stein 5.02.2016 17:53:09
dict(sorted(d.items(), key=lambda x: x[1])),
Dr_Hope 16.07.2019 15:39:48
Нет. Создание диктата из отсортированного списка кортежей снова убивает орден ...
Jean-François Fabre♦ 25.11.2019 20:37:20

В недавнем 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)])
161
3.04.2014 16:59:39
Вопрос не в этом - речь идет не о поддержании порядка ключей, а о «сортировке по значению»
Nas Banov 5.07.2010 07:07:53
@Nas Banov: это НЕ сортировка по ключу. это сортировка в порядке, мы создаем элементы. в нашем случае мы сортируем по значению. к сожалению, был выбран трехэлементный диктат, поэтому порядок был тот же, когда сортировали voth по значению и ключу, поэтому я расширил примерный диктат.
mykhal 5.07.2010 10:56:20
sorted(d.items(), key=lambda x: x[1])Можете ли вы объяснить, что xзначит, почему это может привести x[1]к лямбда? Почему этого не может быть x[0]? Большое спасибо!
JZAU 8.11.2013 05:12:55
@Boern d.items()возвращает контейнер списков, похожий на список (key, value). [0]получает доступ к первому элементу кортежа - ключу - и [1]обращается ко второму элементу - значению.
BallpointBen 10.04.2018 14:29:55
Примечание: В 3,6 (как деталь реализации CPython / PyPy) и в 3,7 ( в качестве гарантии на языке Python), простой dictявляется вставка заказывается, так что вы можете просто заменить OrderedDictс dictдля кода , работающего на современном языке Python. OrderedDictбольше не требуется, если только вам не нужно изменить порядок существующего dictmove_to_end/ popitem) или не нужно сравнение на равенство, чтобы учитывать порядок. Он использует намного больше памяти, чем обычный dict, поэтому, если вы можете, dictэто путь.
ShadowRanger 4.09.2019 13:09:56

Так просто как: 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)- сортировка перебирает ключи словаря, используя количество вхождений слов в качестве ключа сортировки.

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

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

1242
10.03.2020 14:42:24
Это также хорошо, но key=operator.itemgetter(1)должно быть более масштабируемым для эффективности, чемkey=d.get
smci 9.12.2011 21:18:26
@raylu Я наблюдаю поведение "не работает" с помощью itemgetter: ----- from operator import itemgetter d = {"a":7, "b":1, "c":5, "d":3} sorted_keys = sorted(d, key=itemgetter, reverse=True) for key in sorted_keys: print "%s: %d" % (key, d[key]) ----- -> b: 1 c: 5 a: 7 d: 3 Результаты меняются каждый раз, когда я запускаю код: странный , (извините, не могу получить код для правильного отображения)
bli 13.08.2014 15:58:40
@bli sorted_keys = sorted(d.items(), key=itemgetter(1), reverse=True)и for key, val in sorted_keys: print "%s: %d" % (key, val)- itemgetter создают функцию при ее вызове, вы не используете ее напрямую, как в вашем примере. И простая итерация на dict использует ключи без значений
Izkata 19.08.2014 20:21:15
я пришел из будущего, чтобы рассказать вам о том collections.Counter, что есть most_commonметод, который может вас заинтересовать :)
Eevee 25.06.2017 20:47:44
@ Eevee - есть вероятность того, что вас не поймут в коротких комментариях. Amuzing Tidbit: collections.Counterбыл добавлен в 2.7, который был выпущен почти ровно 7 лет назад! (Я тогда не знал об этом - плюс я бы избежал этого в код-гольфе с целью краткости, которая является единственной навязчивой идеей игры)
Nas Banov 28.06.2017 21:56:09
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
12
1.11.2010 12:16:41
вопрос был: сортировка по значению, а не по ключам ... Мне нравится видеть функцию. Вы можете импортировать коллекции и, конечно, использовать отсортированные (data.values ​​())
Remi 30.08.2011 00:38:21

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

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

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

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

42
28.11.2017 13:44:24
Вы пропустите значение из результата
Dejell 7.01.2014 20:54:43
Обратите внимание, что вы итерируете словарь и извлекаете значения по их ключу, поэтому с точки зрения производительности это не оптимальное решение.
Ron Klein 21.09.2016 08:00:26
@Dejell: как говорит автор, он интерпретирует вопрос как «могу ли я получить список ключей, отсортированных по значениям». Нам не нужны значения в результате, они есть в словаре.
Max 12.01.2019 03:19:58

Это код:

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

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

оригинал

{'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
2.03.2016 07:42:26

Часто может быть очень удобно использовать 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
75
24.04.2017 02:11:59
Как я могу преобразовать его обратно в словарь?
rowana 7.02.2017 20:31:44
as_list = [Player (v, k) для (k, v) в d.items ()] as_dict = dict ((p.name, p.score) для p в as_list)
Remi 23.02.2017 12:31:13

Используйте 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)]
6
19.10.2011 06:25:41

Итерируйте через 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
5
30.10.2011 19:42:06

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

import operator
slovar_sorted=sorted(slovar.items(), key=operator.itemgetter(1), reverse=True)
print(slovar_sorted)
5
6.11.2012 19:27:31

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

5
24.01.2012 19:50:43

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

from collections import Counter

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

>> [('python', 5), ('world', 3), ('hello', 1)]    
34
17.05.2019 13:48:42
что если ваш словарь >>> x = {'hello': 1, 'python': 5, 'world': 300}
James Sapam 28.12.2013 13:17:35
@yopy Counter({'hello':1, 'python':5, 'world':300}).most_common()дает [('world', 300), ('python', 5), ('hello', 1)]. Это на самом деле работает для любого типа сортируемых значений (хотя многие другие операции Counter требуют, чтобы значения были сопоставимы с целыми числами).
lvc 28.12.2013 13:58:26

Использование 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
3.04.2014 17:03:51

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

>>> 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)])
19
3.04.2014 17:04:58
Чем это отличается от ответа Ивана Саса ?
Peter Mortensen 3.04.2014 17:07:08

Ради полноты я выкладываю решение с использованием 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
23.03.2013 14:19:53

В 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
22.08.2013 08:38:48
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
13.02.2014 23:59:55

Из-за требований сохранить обратную совместимость со старыми версиями 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)]
4
3.04.2014 17:10:13

Попробуйте следующий подход. Давайте определим словарь 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
25
23.05.2018 23:11:19
Потрясающие! for key, value in sorted(mydict.iteritems(), key=lambda (k,v): v["score"]):позволяет сортировать по подразделу
Andomar 7.07.2017 19:08:07
это дает мне синтаксическую ошибку около лямбды в Python3
Suleman Elahi 6.02.2020 10:44:11

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

>>> 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
25.09.2014 22:56:55
Можем ли мы изменить порядок сортировки, прямо сейчас, это отправка, но я хочу отклонение.
Suleman Elahi 6.02.2020 12:15:21
afaik, вам придется отрицать ваши значения, чтобы изменить порядок
malthe 6.02.2020 13:14:41
вау, я не думаю, что так ... спасибо.
Suleman Elahi 7.02.2020 17:37:34

Вот решение с использованием 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
20.06.2015 01:44:58

Конечно, помните, вам нужно использовать, 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 или выше

9
17.05.2019 16:17:06
обычные словари Python не сохраняют первоначальный порядок - с Python 3.7 они сохраняют .
gerrit 19.12.2018 17:13:36

ОБНОВЛЕНИЕ: 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)])
103
15.12.2015 05:54:53

Начиная с 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 с темой «Python 3.6 dict становится компактный и получает приватную версию, а ключевые слова упорядочиваются « из-за исправления / реализации проблемы 27350 « Компактный и упорядоченный dict » в Python 3.6, теперь мы сможем использовать встроенный dict для поддержания порядка вставки !!

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

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

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

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

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

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

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

Будьте бдительны (но также смотрите обновление ниже 2017-12-15):

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

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

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

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

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

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

72
16.12.2017 15:47:55
Следует подчеркнуть предупреждение на странице «whatsnew», на которую вы ссылались: сохраняющий порядок аспект этой новой реализации считается деталью реализации и на него не следует полагаться . Никто не должен предполагать, что dictтип будет соответствовать порядку вставки в их коде. Это не является частью определения языка, и реализация может измениться в любом будущем выпуске. Продолжайте использовать, OrderedDictчтобы гарантировать заказ.
Alex Riley 10.09.2016 20:15:16
@ajcr спасибо за предостережение, очень признателен - поскольку смайлики и, возможно, были включены в мой ответ, это должно указывать на то, что изменение огромно, но, конечно, доступно только для CPython (эталонная реализация) и PyPy. Для чего-то совершенно другого ... Я редко говорю о деталях, не связанных с реализацией, при кодировании команд человек-машина. Если бы это был только Jython ;-) ... У меня не хватило бы смелости написать это.
Dilettant 10.09.2016 20:22:56
OrderedDictопределенно не будет отброшен; вместо этого он станет тонкой оболочкой для текущей реализации dict (так что вы можете добавить, что он тоже станет более компактным). Добавление этого фрагмента с ImportErrorне совсем лучшей идеей, поскольку вводит в заблуждение читателей, которые OrderedDictбесполезны.
Dimitris Fasarakis Hilliard 10.12.2016 13:33:02
@ JimFasarakis-Hilliard спасибо за отзыв. «Совершенно лучшие идеи» заставили меня улыбнуться - будущее часто трудно предсказать. Но мне нравится, что ваше предложение проверит источники, попробуйте и обновите ответ соответственно. Еще раз спасибо.
Dilettant 10.12.2016 13:58:51
@AlexRiley Это предупреждение больше не является точным. Python3.7 гарантирует упорядоченные словари.
gerrit 19.12.2018 17:12:48

Этот метод не будет использовать лямбду и хорошо работает на 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 ('=======================')
-1
20.03.2018 22:34:09
Из очереди просмотра: Могу ли я попросить вас добавить контекст вокруг вашего исходного кода. Ответы только на код трудно понять. Это поможет вам и будущим читателям, если вы сможете добавить больше информации в свой пост.
HDJEMAI 24.05.2017 03:37:42
это очень неэффективное решение, с линейным поиском и всем
Jean-François Fabre♦ 17.05.2019 19:20:20

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

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)
14
17.05.2019 14:55:22