Як користуватися OrderedDict, упорядкованим словником Python.

Бізнес

Словники Python (об’єкти типу dict) не зберігають порядок елементів; CPython робив це з версії 3.6, але це залежить від реалізації та невизначено в інших реалізаціях; специфікація мови зберегла порядок з 3.7.

OrderedDict надається в модулі колекцій стандартної бібліотеки як словник, який зберігає порядок. Використовувати цей засіб безпечно.

Імпортуйте модуль колекцій. Він входить до стандартної бібліотеки і не потребує встановлення.

import collections

Якщо ви напишете наступне, ви можете опустити колекції. у наступних прикладах.

from collections import OrderedDict

Нижче наведено опис того, як використовувати OrderedDict.

  • Створення об’єкта OrderedDict
  • OrderedDict — це підклас dict
  • Переміщення елементів на початок або кінець
  • Додайте новий елемент у будь-яку позицію.
  • Переставити (змінити порядок) елементів
  • Сортувати елементи за ключем або значенням

Створення об’єкта OrderedDict

Конструктор collections.OrderedDict() можна використовувати для створення об’єкта OrderedDict.

Створіть порожній об’єкт OrderedDict і додайте значення.

od = collections.OrderedDict()

od['k1'] = 1
od['k2'] = 2
od['k3'] = 3

print(od)
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])

Також можна вказати аргументи конструктору.

Ви можете використовувати аргументи ключових слів, послідовності пар ключ-значення (наприклад, кортежі (ключ, значення)) тощо. Останній може бути списком або кортежем, якщо він є парою ключ-значення.

print(collections.OrderedDict(k1=1, k2=2, k3=3))
print(collections.OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)]))
print(collections.OrderedDict((['k1', 1], ['k2', 2], ['k3', 3])))
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])

До версії 3.5 порядок аргументів ключових слів не зберігався, але з версії 3.6 тепер він зберігся.

Змінено у версії 3.6: із прийняттям PEP 468 порядок конструктора OrderedDict і аргументи ключового слова, передані методу update(), зберігаються.
collections — Container datatypes — Python 3.10.0 Documentation

Звичайні словники (об’єкти типу dict) також можна передати конструктору, але у випадку реалізацій, де тип dict не зберігає порядок, OrderedDict, згенерований з нього, також не зберігатиме порядок.

print(collections.OrderedDict({'k1': 1, 'k2': 2, 'k3': 3}))
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])

OrderedDict — це підклас dict

OrderedDict — це підклас dict.

print(issubclass(collections.OrderedDict, dict))
# True

OrderedDict також має ті самі методи, що й dict, а методи отримання, зміни, додавання та видалення елементів такі ж, як і dict.

print(od['k1'])
# 1

od['k2'] = 200
print(od)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3)])

od.update(k4=4, k5=5)
print(od)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3), ('k4', 4), ('k5', 5)])

del od['k4'], od['k5']
print(od)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3)])

Подробиці дивіться в наступній статті.

Переміщення елементів на початок або кінець

Ви можете використовувати власний метод OrderedDict move_to_end(), щоб перемістити елемент на початок або кінець.

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

od.move_to_end('k1')
print(od)
# OrderedDict([('k2', 200), ('k3', 3), ('k1', 1)])

od.move_to_end('k1', False)
print(od)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3)])

Додайте новий елемент у будь-яку позицію.

Можна створити новий об’єкт OrderedDict з новим елементом, доданим у довільній позиції. Зокрема, це можна зробити в наступному потоці.

  1. Перерахуйте об’єкти перегляду, які можна отримати за допомогою методу items() за допомогою list().
  2. Додайте кортеж (ключ, значення) пар ключ-значення в метод insert() списку
  3. Створіть новий об’єкт, передавши його конструктору collections.OrderedDict()
l = list(od.items())
print(l)
# [('k1', 1), ('k2', 200), ('k3', 3)]

l.insert(1, ('kx', -1))
print(l)
# [('k1', 1), ('kx', -1), ('k2', 200), ('k3', 3)]

od = collections.OrderedDict(l)
print(od)
# OrderedDict([('k1', 1), ('kx', -1), ('k2', 200), ('k3', 3)])

insert() визначає позицію, яка буде вставлена ​​як перший аргумент, а елемент, який потрібно вставити, як другий аргумент.

У прикладі новий об’єкт призначається вихідній змінній, а нові елементи не додаються до самого оригінального об’єкта.

Переставити (змінити порядок) елементів

Заміна елементів – це той самий процес, що і в прикладі вище.

  1. Перерахуйте об’єкти перегляду, які можна отримати за допомогою методу items() за допомогою list().
  2. Замінити елементи в списку
  3. Створіть новий об’єкт, передавши його конструктору collections.OrderedDict()
l = list(od.items())
print(l)
# [('k1', 1), ('kx', -1), ('k2', 200), ('k3', 3)]

l[0], l[2] = l[2], l[0]
print(l)
# [('k2', 200), ('kx', -1), ('k1', 1), ('k3', 3)]

od = collections.OrderedDict(l)
print(od)
# OrderedDict([('k2', 200), ('kx', -1), ('k1', 1), ('k3', 3)])

Якщо ви хочете вказати ключ і замінити його, скористайтеся методом index(), щоб отримати індекс (позицію) зі списку ключів, як показано нижче.

l = list(od.items())
k = list(od.keys())
print(k)
# ['k2', 'kx', 'k1', 'k3']

print(k.index('kx'))
# 1

l[k.index('kx')], l[k.index('k3')] = l[k.index('k3')], l[k.index('kx')]
print(l)
# [('k2', 200), ('k3', 3), ('k1', 1), ('kx', -1)]

od = collections.OrderedDict(l)
print(od)
# OrderedDict([('k2', 200), ('k3', 3), ('k1', 1), ('kx', -1)])

Сортувати елементи за ключем або значенням

Створіть список кортежів (ключ, значення) відсортованих пар ключ-значення на основі об’єкта перегляду, який можна отримати за допомогою методу items(), і передайте його конструктору collections.OrderedDict(), щоб створити новий об’єкт.

Сортування виконується шляхом визначення анонімної функції (лямбда-виразу), яка повертає ключ або значення з кортежу (ключ, значення) як ключ аргументу вбудованої функції sorted().

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

print(od)
# OrderedDict([('k2', 200), ('k3', 3), ('k1', 1), ('kx', -1)])

od_sorted_key = collections.OrderedDict(
    sorted(od.items(), key=lambda x: x[0])
)
print(od_sorted_key)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3), ('kx', -1)])

od_sorted_value = collections.OrderedDict(
    sorted(od.items(), key=lambda x: x[1], reverse=True)
)
print(od_sorted_value)
# OrderedDict([('k2', 200), ('k3', 3), ('k1', 1), ('kx', -1)])