Оригінальна публікація: Sort Dictionary by Value in Python – How to Sort a Dict

Словник у Python — це структура, яка за замовчуванням невпорядкована. Іноді потрібно відсортувати словник за ключем чи значенням, щоб полегшити запит.

Проблема в тому, що відсортувати словник за значенням — непроста справа, оскільки Python не має вбудованого методу.

Однак я знайшов спосіб відсортувати словник за значенням. У цій публікації я поділюсь ним.

Що ми розглянемо:

Як відсортувати дані за допомогою методу sorted()

Метод sorted() сортує ітерабельні дані, як-от списки, кортежі та словники. Але він сортує лише за ключем.

Метод sorted() розташовує відсортовані елементи у списку. Це ще одна проблема, оскільки ми хочемо, щоб словник залишався словником.

Наприклад, sorted() розставив список в алфавітному порядку:

persons = ['Chris', 'Amber', 'David', 'El-dorado', 'Brad', 'Folake']
sortedPersons = sorted(persons)

print(sortedPersons)
# Вивід: ['Amber', 'Brad', 'Chris', 'David', 'El-dorado', 'Folake']

Ще один приклад. Метод sorted() відсортував числа кортежу в порядку зростання:

numbers = (14, 3, 1, 4, 2, 9, 8, 10, 13, 12)
sortedNumbers = sorted(numbers)

print(sortedNumbers)
# Вивід: [1, 2, 3, 4, 8, 9, 10, 12, 13, 14]

Якщо використати метод sorted() зі словником, повернуться лише ключі у вигляді списку:

my_dict = { 'num6': 6, 'num3': 3, 'num2': 2, 'num4': 4, 'num1': 1, 'num5': 5}
sortedDict = sorted(my_dict)

print(sortedDict)
# Вивід: ['num1', 'num2', 'num3', 'num4', 'num5', 'num6']

Це не те, що потрібно. Нам потрібно відсортувати словник за значенням так, щоб він залишився словником. Зараз я покажу, як це зробити.

Як працює метод sorted()

Щоб відсортувати словник, ми будемо використовувати функцію sorted, але складнішим способом. Не переживайте, я поясню все, що потрібно знати.

Оскільки ми надалі використовуватимемо метод sorted(), варто пояснити його в деталях.

Параметри методу sorted()

Метод sorted() може приймати 3 параметри:

  • ітерабельні — дані для ітерації; це може бути кортеж, список чи словник;
  • key — додаткове значення; функція, яка дозволяє виконати сортування;
  • reverse — ще одне додаткове значення, яке допомагає відсортувати дані у порядку зростання чи спадання.

Ми передаватимемо параметр key до методу sorted(), щоб отримати словник, відсортований за значенням.

Тепер час відсортувати словник за значенням та переконатись, що він залишиться словником.

Як відсортувати словник за допомогою методу sorted()

Щоб правильно відсортувати словник за значенням за допомогою методу sorted(), вам знадобиться:

  • передати словник до методу sorted() як перший аргумент;
  • використати метод items() на словнику, щоб знайти ключі та значення;
  • написати функцію lambda, щоб отримати значення, знайдені за допомогою методу item().

Ось приклад:

footballers_goals = {'Eusebio': 120, 'Cruyff': 104, 'Pele': 150, 'Ronaldo': 132, 'Messi': 125}

sorted_footballers_by_goals = sorted(footballers_goals.items(), key=lambda x:x[1])
print(sorted_footballers_by_goals)

Як я казав раніше, нам потрібно отримати значення словника, щоб відсортувати його за значенням. Через це ви можете бачити 1 у лямбді-функції.

1 представляє індекси значень. Ключами є 0. Пам’ятайте, що програміст починає рахувати з 0, а не 1.

Завдяки вищеподаному коду я отримав наступне:

# [('Cruyff', 104), ('Eusebio', 120), ('Messi', 125), ('Ronaldo', 132), ('Pele', 150)]

Ось повний код:

footballers_goals = {'Eusebio': 120, 'Cruyff': 104, 'Pele': 150, 'Ronaldo': 132, 'Messi': 125}

sorted_footballers_by_goals = sorted(footballers_goals.items(), key=lambda x:x[1])
print(sorted_footballers_by_goals)

# Вивід: [('Cruyff', 104), ('Eusebio', 120), ('Messi', 125), ('Ronaldo', 132), ('Pele', 150)]

Як бачите, словник відсортований за значенням у порядку зростання. Сортування також можна виконати у порядку спадання. Але ми розглянемо це пізніше, оскільки досі маємо проблему з отриманим результатом.

Проблема в тому, що словник більше не словник. Окремі ключі та значення були розміщені у кортежі, а потім зведені у список. Пам’ятайте, що результат методу sorted() розміщується у списку.

Ми змогли відсортувати елементи у словнику за значенням. Залишилось перетворити його назад у словник.

Як перетворити отриманий список у словник

Щоб перетворити отриманий список у словник, вам не потрібно писати ще одну складну функцію чи цикл. Вам просто потрібно передати змінну з отриманим списком до методу dict().

converted_dict = dict(sorted_footballers_by_goals)
print(converted_dict)
# Вивід: {'Cruyff': 104, 'Eusebio': 120, 'Messi': 125, 'Ronaldo': 132, 'Pele': 150}

Пам’ятайте, що ми зберегли відсортований словник у змінній під назвою sorted_footballers_by_goals. Тепер цю змінну потрібно передати до dict().

Повністю код виглядає так:

footballers_goals = {'Eusebio': 120, 'Cruyff': 104, 'Pele': 150, 'Ronaldo': 132, 'Messi': 125}

sorted_footballers_by_goals = sorted(footballers_goals.items(), key=lambda x:x[1])
converted_dict = dict(sorted_footballers_by_goals)

print(converted_dict)
# Вивід: {'Cruyff': 104, 'Eusebio': 120, 'Messi': 125, 'Ronaldo': 132, 'Pele': 150}

Це все! Ми відсортували елементи словника та перетворили їх назад у словник.

Як відсортувати словник за значенням у порядку зростання чи спадання

Пам’ятайте, що метод sorted() приймає третє значення під назвою reverse.

reverse зі значенням True впорядкує відсортований словник у порядку спадання.

footballers_goals = {'Eusebio': 120, 'Cruyff': 104, 'Pele': 150, 'Ronaldo': 132, 'Messi': 125}

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

print(converted_dict)
# Вивід: {'Pele': 150, 'Ronaldo': 132, 'Messi': 125, 'Eusebio': 120, 'Cruyff': 104}

Як бачите, вивід у зворотньому порядку, оскільки ми передали reverse=True до методу sorted().

Якщо ви взагалі не налаштуєте reverse чи надасте значення false, словник буде впорядкований у порядку зростання за замовчуванням.

Висновок

Мої вітання. Тепер ви можете відсортувати словник за значенням, не маючи вбудованого методу чи функції у Python.

Під час написання цієї публікації мене дещо зацікавило. Пам’ятайте, ми могли використати sorted() одразу на словнику. У результаті ми отримали список, правда ми отримали лише ключі без значень.

Якщо ми перетворимо список у словник за допомогою dict(), ми отримаємо бажаний результат? Поглянемо:

my_dict = { 'num6': 6, 'num3': 3, 'num2': 2, 'num4': 4, 'num1': 1, 'num5': 5}
sortedDict = sorted(my_dict)

converted_dict = dict(sortedDict)
print(converted_dict)
"""
Вивід: 
dict_by_value.py
Traceback (most recent call last):
  File "sort_dict_by_value.py", line 17, in <module>
    converted_dict = dict(sortedDict)
ValueError: dictionary update sequence element #0 has length 4; 2 is required
"""

Ми отримали помилку! Якщо ви хочете створити словник з списку, потрібно використати розуміння словника. А якщо ви використовуєте розуміння словника для цього типу даних, потрібно вказувати одне значення для всіх записів. Це суперечить меті сортування словника за значенням, тому нам цього не потрібно.

Якщо хочете дізнатись більше про розуміння словника, вам варто прочитати цю публікацію.

Дякую, що прочитали!