Как отсортировать словарь в Python

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

Возможность сортировать словари появилась в Python 3.7. Раньше это было невозможно.

БЕСПЛАТНО СКАЧАТЬ КНИГИ по Python на русском языке можно у нас в телеграм канале "Python книги на русском"

Чтобы отсортировать словарь, нужно сделать следующее:

  1. Создать словарь (множество пар ключ-значение)
  2. Определиться, каким образом будет происходить сортировка: по ключу или по значению
  3. Выбрать порядок сортировки: восходящий или нисходящий
  4. Вызвать встроенную функцию sorted()

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

data = {
    "Bob": 23,
    "Charlie": 36,
    "Alice": 72,
    "Eric": 18,
    "David": 9
}

sort_data = sorted(data.items(), key=lambda x: x[1], reverse=True)
for i in sort_data:
    print(i[0], i[1])

Эта операция даст нам следующий результат:

Alice 72
Charlie 36
Bob 23
Eric 18
David 9

В этой статье мы подробно разберем сортировку словарей в Python. Вы узнаете, как отсортировать словарь по ключам и по значениям в восходящем и нисходящем порядке. Кроме того, мы разберем все аргументы функции sorted(), чтобы лучше понимать, как она работает.

Функция sorted() в Python

В языке Python есть встроенная функция sorted(), которую можно использовать для сортировки итерируемых объектов, таких как списки или словари.

Ее синтаксис имеет следующий вид:

sorted(iterable, key=None, reverse=False)

Теперь давайте поподробней рассмотрим аргументы функции sorted():

  • iterable: это последовательность или набор значений (например, список или словарь), который необходимо отсортировать
  • reverse: необязательный параметр, по умолчанию имеет значение False
    • если значение данного параметра равно True, то сортировка производится в порядке убывания
    • если значение равно False, то сортировка происходит в порядке возрастания
  • key: также необязательный параметр, он дает возможность подключить определенную функцию, которая описывает логику сортировки

Теперь давайте посмотрим на функцию sorted() в действии. Отсортируем словарь несколькими способами.

Сортировка словаря по значениям

В языке Python словарь представляет собой набор пар ключ-значение. Идея словаря в том, чтобы хранить значения, доступные через ключи, а не индексы, как в списках. Это делает словари отличными хранилищами для размеченных и структурированных данных.

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

Чтобы отсортировать словарь по значениям, вам нужно сообщить об этом функции sorted(), так как по умолчанию она производит сортировку по ключам. Для этого надо при вызове функции задать необязательный параметр key.

Параметр key работает как функция сортировки. Другими словами, функция sorted() выполняет встроенный алгоритм сортировки элементов списка и вызывает функцию key для каждого элемента, чтобы отсортировать их желаемым образом.

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

Теперь рассмотрим ряд примеров.

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

Например, имея словарь с именами учащихся, сопоставленными с их возрастом, давайте отсортируем данные словаря в порядке возрастания возраста.

Примечание: Функция sorted() не возвращает словарь. Вместо этого она возвращает список, состоящий из кортежей, в которых находятся пары ключ-значение. Чтобы превратить данный результат словарь, нужно передать этот список в функцию dict().

Вот код приведенного примера:

data = {
    "Bob": 23,
    "Charlie": 36,
    "Alice": 72,
    "Eric": 18,
    "David": 9
}

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

sort_data_dict = dict(sort_data)
print(sort_data_dict)

Результат:

{'David': 9, 'Eric': 18, 'Bob': 23, 'Charlie': 36, 'Alice': 72}

В дальнейшем, для лучшего понимания того, что происходит, мы более подробно рассмотрим функцию key=lamda x: x[1]. А пока продолжим сортировать.

Как отсортировать словарь по убыванию значений

Чтобы отсортировать словарь по убыванию, нужно присвоить необязательному параметру reverse значение True.

Теперь код будет выглядеть следующим образом:

data = {
    "Bob": 23,
    "Charlie": 36,
    "Alice": 72,
    "Eric": 18,
    "David": 9
}

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

sort_data_dict = dict(sort_data)
print(sort_data_dict)

Результат:

{'Alice': 72, 'Charlie': 36, 'Bob': 23, 'Eric': 18, 'David': 9}

Далее перейдем к сортировке словарей по ключам.

Сортировка словаря по ключам

Чтобы отсортировать словарь по ключам в Python, надо просто вызвать функцию sorted() для элементов словаря. Вообще функция sorted() по умолчанию сортирует словарь именно по ключам, так что такая сортировка проще, чем по значениям.

Давайте рассмотрим примеры сортировки по ключам как по возрастанию, так и по убыванию.

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

Например, отсортируем словарь, содержащий имена и возраст людей, по именам в возрастающем (алфавитном) порядке:

data = {
    "Bob": 23,
    "Charlie": 36,
    "Alice": 72,
    "Eric": 18,
    "David": 9
}

sort_data = sorted(data.items())

sort_data_dict = dict(sort_data)
print(sort_data_dict)

Результат:

{'Alice': 72, 'Bob': 23, 'Charlie': 36, 'David': 9, 'Eric': 18}

Как отсортировать словарь по убыванию ключей

А теперь отсортируем тот же словарь по ключам в убывающем алфавитном порядке.

data = {
    "Bob": 23,
    "Charlie": 36,
    "Alice": 72,
    "Eric": 18,
    "David": 9
}

sort_data = sorted(data.items(), reverse=True)

sort_data_dict = dict(sort_data)
print(sort_data_dict)

Результат:

{'Eric': 18, 'David': 9, 'Charlie': 36, 'Bob': 23, 'Alice': 72}

А теперь давайте более подробно рассмотрим аргументы функции sorted(). Если вы уже все поняли, то не стесняйтесь пропустить следующую главу.

Параметры функции sorted()

Были ли у вас трудности с пониманием того, как на самом деле работает сортировка словаря с использованием лямбда-функций в приведенных выше примерах? Если да, то разбор аргументов функции sorted() вам поможет.

К концу этой главы вы лучше разберетесь, как на самом деле работает данный код:

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

Начнем с первого аргумента, а именно с dict.items().

dict.items()

При работе со словарями в Python можно получить доступ к парам ключ-значение при помощи оператора [].

dict["somevalue"]

Но когда дело доходит до перебора словаря, напрямую обратиться к словарю невозможно. Вместо этого нужно преобразовать объекты словаря в последовательность кортежей, где каждый кортеж состоит из двух элементов (ключа и соответствующего значения).

И для этого существует встроенный метод – dict.items().

Ещё раз: перебрать словарь и получить при этом доступ к данным ключ-значение можно только при помощи метода dict.items().

То же самое относится к сортировке словаря при помощи функции sorted(). Под капотом у нее работает цикл, поэтому ей нужно предоставить список кортежей ключ-значение при помощи метода dict.items().

Теперь рассмотрим аргумент, в котором используется лямбда-функция. Это, вероятно, самая запутанная часть функции sorted(), поэтому потребуется довольно много объяснений.

key=lambda x: x[1]

Повторим, что параметр key является необязательным аргументом функции sorted(). Он работает как функция сортировки, которую алгоритм запускает для каждого элемента словаря.

По умолчанию сортировка словарей производится по ключам. Чтобы это изменить, нужно сообщить функции sorted(), что надо использовать значения.

Для этого используется аргумент этой функции key, который принимает, в свою очередь, функцию сортировки. Чтобы выполнить сортировку по значениям, функция сортировки должна взять пару ключ-значение из словаря и вернуть ее значение.

Для этого можно использовать обычную функцию.

Например, вот функция, которая принимает пару ключ-значение и возвращает значение:

def getvalue(pair):
    return pair[1]

Теперь можно передать эту функцию в параметр key при вызове функции sorted().

Например, отсортируем словарь, состоящий из пар имя-возраст, по возрасту, то есть по значениям:

data = { "Bob": 12, "Charlie": 7, "Alice": 18, }

def getvalue(pair):
    return pair[1]

sort_data = sorted(data.items(), key=getvalue)

sort_data_dict = dict(sort_data)
print(sort_data_dict)

Результат:

{'Charlie': 7, 'Bob': 12, 'Alice': 18}

Теперь давайте подробнее рассмотрим, как и почему это работает:

  • при помощи цикла перебирается каждая пара ключ-значение
  • для каждой пары ключ-значение вызывается функция getvalue
  • производится сортировка на основании значений, возвращаемых функцией getvalue

В этом случае функция возвращает значение, поэтому функция sorted() просматривает каждое такое значение и сортирует словарь на их основе.

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

Далее рассмотрим использование лямбда-функции, что соответствует лучшим практикам программирования на языке Python.

Использование лямбда-функции вместо обычной

Указание отдельной функции для сортировки словаря приводит к появлению ненужных строк кода, а это не соответствует best practices Python.

В предыдущем примере функция getvalue используется только один раз. Это означает, что после сортировки в кодовой базе остается висящим бесполезное определение этой функции. Это не идеально.

В таких ситуациях выручает лямбда-функция.

Лямбда-функция — это анонимная, то есть не имеющая имени функция. Она может принимать любое количество аргументов, но иметь только одно выражение. Таким образом, лямбда-функция может использоваться вместо обычной функции с одним выражением.

Обычно синтаксис лямбда-функции имеет следующий вид:

lambda аргументы : выражение

Здесь аргументы — это не что иное, как традиционные аргументы функции, а выражение — это строка кода Python, которая запускает саму функцию.

Итак, обычная функция имеет следующий вид:

def getvalue(pair):
    return pair[1]

Теперь давайте преобразуем это в лямбда-функцию:

lambda pair : pair[1]

Эта лямбда-функция работает точно так же, как и функция getvalue. Но так как лямбда-функция не имеет имени, на нее невозможно ссылаться. Другими словами, как отдельное выражение лямбда-функция бесполезна.

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

Теперь вернемся к сортировке словарей. Вместо того, чтобы отдельно указывать функцию getvalue, используем лямбда-выражение:

data = { "Bob": 12, "Charlie": 7, "Alice": 18, }

sort_data = sorted(data.items(), key=lambda pair : pair[1])

sort_data_dict = dict(sort_data)
print(sort_data_dict)

В каком-то смысле функция getvalue была реализована непосредственно при вызове функции sorted() и сразу же использована.

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

{'Charlie': 7, 'Bob': 12, 'Alice': 18}

Таким образом, используя лямбду-функцию, можно сделать код короче и качественнее.

Обратите внимание, что аргументы лямбда-функции можно называть как угодно и не обязательно использовать слово pair. То есть можно просто использовать x, как и было сделано ранее.

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

Теперь должно быть понятно, как работает функция в аргументе key при вызове функции sorted().

Еще надо заметить, что функция в аргументе key может быть и гораздо более сложной. Например, давайте отсортируем словарь на основании того, является ли возраст (age) четным:

data = { "Bob": 12, "Charlie": 7, "Alice": 18, "David": 3}

sort_data = sorted(data.items(), key=lambda pair : pair[1] % 2 == 0)

sort_data_dict = dict(sort_data)
print(sort_data_dict)

Результат:

{'Charlie': 7, 'David': 3, 'Bob': 12, 'Alice': 18}

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

reverse=True

Аргумент reverse — это третий аргумент в вызове функции sorted(). Это необязательный аргумент. Он определяет порядок, в котором выполняется сортировка.

По умолчанию этот аргумент имеет значение False. Это означает, что по умолчанию сортировка происходит по возрастанию.

Итак, мы разобрали, как работает функция sorted(). Теперь давайте посмотрим, как выполняется сортировка словаря в версиях Python ниже 3.7.

Как отсортировать словарь в Python до версии 3.7

До версии 3.7 словари в Python были неупорядоченными сущностями. Это, в принципе, означает, что их сортировка достаточно бессмысленная операция.

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

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

  1. Берем пары ключ-значение
  2. Сортируем пары ключ-значение. Это дает нам в результате отсортированный список кортежей
  3. Преобразуем этот список в тип OrderedDict

Вот пример такой сортировки:

from collections import OrderedDict

data = {
    "Bob": 23,
    "Charlie": 36,
    "Alice": 72,
    "Eric": 18,
    "David": 9
}

sort_data = sorted(data.items(), key=lambda x: x[1])
sort_data_dict = OrderedDict(sort_data)

print(sort_data_dict)

Результат:

OrderedDict([('David', 9), ('Eric', 18), ('Bob', 23), ('Charlie', 36), ('Alice', 72)])

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

Заключение

Сегодня вы узнали, как отсортировать словарь в Python.

Напомним, что в Python, начиная с версии 3.7, словари сохраняют порядок элементов. Это значит, что их можно сортировать.

Чтобы отсортировать словарь, используйте встроенную функцию sorted(), передав ей следующие аргументы:

  1. iterable: элементы словаря
  2. key: функцию сортировки
  3. reverse: порядок сортировки (по возрастанию или по убыванию)

Спасибо за внимание и удачного кодинга!

Перевод статьи Arturri Jalli “How to Sort a Dictionary in Python”.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *