У меня есть словарь значений, считываемых из двух полей в базе данных: строковое и числовое. Строковое поле уникально, поэтому это ключ словаря.
Я могу отсортировать ключи, но как отсортировать их по значениям?
Примечание. Я прочитал здесь вопрос о переполнении стека Как отсортировать список словарей по значению словаря? < / em> и, вероятно, мог бы изменить мой код, чтобы иметь список словарей, но поскольку мне действительно не нужен список словарей, я хотел знать, есть ли более простое решение для сортировки в порядке возрастания или убывания.
31 ответ
Python 3.7+ или CPython 3.6
Dicts сохраняет порядок вставки в Python 3.7+. То же самое в CPython 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}
Или
>>> dict(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, поскольку распаковка запрещена, мы можем использовать
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)
sorted_x.reverse()
даст вам порядок по убыванию (по второму элементу кортежа)
sorted()
, гораздо эффективнее передать аргумент reverse=True
.
sorted(d.items(), key=lambda x: x[1])
. Будет ли это работать в Python 2.x?
key=lambda item :item[1]
, пожалуйста? Часть, которую я не совсем понимаю, это item[1]
, это потому, что когда мы делаем x.items()
, он возвращает пары ключ-значение, и с этим мы можем подключиться к значению, выполнив item[1]
?
Начиная с 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)
Уступая в этом случае (для нового встроенного dict Python 3.6+!):
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 < a href = "http://bugs.python.org/issue27350" rel = "noreferrer"> "Компактный и упорядоченный dict" в Python 3.6 теперь мы сможем использовать встроенный dict для поддержки вставить заказ !!
Надеюсь, это приведет к реализации тонкого слоя OrderedDict в качестве первого шага. Как указал @ JimFasarakis-Hilliard, некоторые видят варианты использования типа OrderedDict также в будущем. Я думаю, что сообщество Python в целом внимательно изучит, выдержит ли это испытание временем, и каковы будут следующие шаги.
Пора переосмыслить наши привычки кодирования, чтобы не упустить возможности, которые открывает стабильное упорядочение:
- Ключевые слова аргументы и
- (промежуточное) хранилище dict
Во-первых, потому что в некоторых случаях упрощает диспетчеризацию при реализации функций и методов.
Второе, поскольку оно способствует более простому использованию dict
в качестве промежуточного хранилища в конвейерах обработки.
Раймонд Хеттингер любезно предоставил документацию, объясняющую "whatsnew36) не придирки, но цитата была немного пессимистичной ;-). Он продолжается как «(это может измениться в будущем, но желательно иметь эту новую реализацию dict на языке в нескольких выпусках, прежде чем изменять спецификацию языка, чтобы требовать семантику сохранения порядка для всех текущих и будущих реализаций Python; это также помогает сохранить обратную совместимость со старыми версиями языка, в которых все еще действует случайный порядок итераций, например Python 3.5) ".
Так же, как и в некоторых человеческих языках (например, немецком), использование формирует язык, и воля теперь была объявлена ... в whatsnew36.
Обновление 2017-12-15:
В письме в список разработчиков python Гвидо ван Россум заявил:
Сделай это так. «Dict сохраняет порядок размещения» - таково постановление. Спасибо!
Итак, побочный эффект порядка вставки dict в версии 3.6 CPython теперь становится частью спецификации языка (а не только деталью реализации). В этой цепочке писем также всплыли некоторые отличительные цели дизайна для collections.OrderedDict
, о чем во время обсуждения напомнил Раймонд Хеттингер.
OrderedDict
определенно не выпадет; вместо этого он станет тонкой оберткой вокруг текущей реализации dict (так что вы можете добавить, что он также станет более компактным). Добавление этого фрагмента с ImportError
не самая лучшая идея, поскольку вводит читателей в заблуждение, что OrderedDict
бесполезен.
В последней версии 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 ведет себя как обычный диктатор:
>>> 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)])
sorted(d.items(), key=lambda x: x[1])
Вы можете объяснить, что означает x
, почему он может преобразовать x[1]
в лямбда? Почему это не может быть x[0]
? Большое спасибо!
d.items()
возвращает похожий на список контейнер кортежей (key, value)
. [0]
обращается к первому элементу кортежа - ключу - а [1]
обращается ко второму элементу - значению.
dict
также является упорядоченным, поэтому вы можете просто заменить OrderedDict
на dict
для кода, работающего на современном Python. OrderedDict
на самом деле больше не нужен, если только вам не нужно изменить порядок существующего dict
(с move_to_end
/ popitem
) или вам нужно, чтобы сравнения на равенство были чувствительными к порядку. Он использует намного больше памяти, чем простой dict
, поэтому, если вы можете, dict
- это то, что вам нужно.
Так просто: sorted(dict1, key=dict1.get)
Что ж, на самом деле можно сделать «сортировку по словарным значениям». Недавно мне пришлось сделать это в Code Golf (вопрос о переполнении стека Код для гольфа: Диаграмма частоты использования слов ). В сокращенном виде проблема была такого рода: учитывая текст, посчитайте, как часто встречается каждое слово, и отобразите список самых популярных слов, отсортированных по убыванию частоты.
Если вы создаете словарь со словами в качестве ключей и количеством вхождений каждого слова в качестве значения, упрощенный здесь как:
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])
Я пишу это подробное объяснение, чтобы проиллюстрировать, что люди часто имеют в виду под словами «Я могу легко отсортировать словарь по ключу, но как отсортировать по значению» - и я думаю, что в исходном сообщении была предпринята попытка решить эту проблему. И решение состоит в том, чтобы составить своего рода список ключей на основе значений, как показано выше.
key=operator.itemgetter(1)
должно быть более масштабируемым для повышения эффективности, чем key=d.get
sorted_keys = sorted(d.items(), key=itemgetter(1), reverse=True)
и for key, val in sorted_keys: print "%s: %d" % (key, val)
- itemgetter создает функцию при ее вызове, вы не используете ее напрямую, как в вашем примере. И простая итерация в dict использует ключи без значений
collections.Counter
, в котором есть метод most_common
, который может вас заинтересовать :)
У меня была такая же проблема, и я решил ее так:
WantedOutput = sorted(MyDict, key=lambda x : MyDict[x])
(Люди, которые отвечают «Невозможно сортировать диктовку», не читали вопрос! Фактически, «Я могу сортировать по ключам, но как я могу сортировать по значениям?» Явно означает, что ему нужен список ключи отсортированы по значению их значений.)
Обратите внимание, что порядок не определен четко (ключи с одинаковым значением будут располагаться в произвольном порядке в списке вывода).
Это код:
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}
Рофл
{'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}
Попробуйте следующий подход. Давайте определим словарь 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
for key, value in sorted(mydict.iteritems(), key=lambda (k,v): v["score"]):
позволяет сортировать по подключам
Вы можете использовать collections.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)])
Вы можете использовать skip 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()
, тогда вы будете выполнять итерацию в отсортированном порядке по значению.
Это реализовано с использованием структуры данных пропустить список.
Начиная с 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.
dict(sorted(words.items(), key=lambda x: x[1], reverse=True))
для DESC
Практически то же самое, что и ответ Хэнка Гэя:
sorted([(value,key) for (key,value) in mydict.items()])
Или немного оптимизирован, как предложил Джон Фухи:
sorted((value,key) for (key,value) in mydict.items())
[(key, value) for (value, key) in sorted_list_of_tuples]
sorted
все равно придется перестраивать список, и перестройка из gencomp будет быстрее. Хорошо для кодгольфинга, плохо для скорости. Оставьте уродливую версию ([])
.
{x: v for x, v in sorted((value, key) for (key, value) in mydict.items())}
Как указал Дилетант, Python 3.6 теперь сохраняет порядок ! Я подумал, что поделюсь написанной мной функцией, которая упрощает сортировку итерации (кортеж, список, dict). В последнем случае вы можете сортировать либо по ключам, либо по значениям, и это может учитывать числовое сравнение. Только для> = 3.6!
Когда вы пытаетесь использовать sorted на итерации, которая содержит, например, строки, а также целые числа, sorted () завершится ошибкой. Конечно, вы можете принудительно сравнивать строки с помощью str (). Однако в некоторых случаях вы хотите выполнить фактическое числовое сравнение, когда 12
меньше, чем 20
(что не относится к сравнению строк). Итак, я придумал следующее. Если вам нужно явное числовое сравнение, вы можете использовать флаг num_as_num
, который будет пытаться выполнить явную числовую сортировку, пытаясь преобразовать все значения в числа с плавающей запятой. Если это удастся, он выполнит числовую сортировку, в противном случае он прибегнет к сравнению строк.
Комментарии по улучшению приветствуются.
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")
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
Используйте 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)]
Конечно, помните, что вам нужно использовать 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 или более поздней версии.
Вы также можете использовать пользовательскую функцию, которую можно передать параметру key.
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)
Это работает в 3.1.x:
import operator
slovar_sorted=sorted(slovar.items(), key=operator.itemgetter(1), reverse=True)
print(slovar_sorted)
Если ваши значения являются целыми числами и вы используете Python 2.7 или новее, вы можете использовать collections.Counter
вместо dict
. Метод most_common
предоставит вам все элементы, отсортированные по значению.
Я только что освоил соответствующий навык на Python для всех< /а>эм>.
Вы можете использовать временный список, который поможет вам отсортировать словарь:
# 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))
Пример вывода:
# Ascending 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')]
Для полноты картины я публикую решение с использованием 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)]
Решение для коллекций, упомянутое в другом ответе, абсолютно превосходно, потому что вы сохраняете связь между ключом и значением, что в случае словарей чрезвычайно важно.
Я не согласен с выбором номер один, представленным в другом ответе, потому что он выбрасывает ключи.
Я использовал решение, упомянутое выше (код показан ниже), и сохранил доступ как к ключам, так и к значениям, и в моем случае упорядочение было по значениям, но важность заключалась в порядке ключей после упорядочивания значений.
from collections import Counter
x = {'hello':1, 'python':5, 'world':3}
c=Counter(x)
print( c.most_common() )
>> [('python', 5), ('world', 3), ('hello', 1)]
Вы можете использовать:
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)]
key=lambda (k, v): v
лично
(k,v)
? Вот что я получаю с Python 2.7.10. @Nyxynyx добавьте параметр reverse = True для сортировки в порядке убывания.
(k, v)
, но он недоступен в Python 3, где распаковка параметра кортежа была удалена.
OrderedDict()
, вы получите (упорядоченный) dict вместо списка кортежей!
Вы можете создать «инвертированный индекс», а также
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]
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
Словари нельзя отсортировать, но из них можно составить отсортированный список.
Отсортированный список значений dict:
sorted(d.values())
Список пар (ключ, значение), отсортированный по значению:
from operator import itemgetter
sorted(d.items(), key=itemgetter(1))
Использование Python 3.5
Хотя я нашел принятый ответ полезным, я также был удивлен, что он не был обновлен для ссылки на OrderedDict из модуля collections стандартной библиотеки в качестве жизнеспособной современной альтернативы, предназначенной для решения именно этого типа проблем.
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)])
Итерируйте по словарю и отсортируйте его по значениям в порядке убывания:
$ 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
В 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.
Наслаждаться ;-)
Вот решение с использованием zip для 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')]
Если значения числовые, вы также можете использовать Counter
из < a href = "https://docs.python.org/library/collections.html" rel = "noreferrer"> коллекции .
from collections import Counter
x = {'hello': 1, 'python': 5, 'world': 3}
c = Counter(x)
print(c.most_common())
>> [('python', 5), ('world', 3), ('hello', 1)]
Counter({'hello':1, 'python':5, 'world':300}).most_common()
дает [('world', 300), ('python', 5), ('hello', 1)]
. Это действительно работает для любого сортируемого типа значения (хотя многие другие операции счетчика требуют, чтобы значения были сопоставимы с целыми числами).
Часто бывает очень удобно использовать 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)
Теперь вы можете узнать имя и счет, скажем, второго лучшего игрока (индекс = 1), очень питонически следующим образом:
player = best[1]
player.name
'Richard'
player.score
7
Похожие вопросы
Новые вопросы
python
Python — это мультипарадигмальный многоцелевой язык программирования с динамической типизацией. Он предназначен для быстрого изучения, понимания и использования, а также обеспечивает чистый и унифицированный синтаксис. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Если у вас есть вопросы о версии Python, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas, NumPy) укажите это в тегах.