Как да използвате OrderedDict, подреден речник в Python.

Бизнес

Речниците на Python (обекти от тип dict) не запазват реда на елементите; CPython го прави от версия 3.6 насам, но това зависи от имплементацията и е неопределено в други имплементации; спецификацията на езика запазва реда от версия 3.7 насам.

OrderedDict се предоставя в модула collections на стандартната библиотека като речник, който запазва реда. Безопасно е да се използва той.

Импортиране на модула за колекции. Той е включен в стандартната библиотека и не е необходимо да се инсталира.

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

Вижте следната статия за подробности.

Преместване на елементи в началото или в края

Можете да използвате собствения метод move_to_end() на OrderedDict, за да преместите даден елемент в началото или в края.

Посочете ключа като първи аргумент. По подразбиране се премества в края, но ако вторият аргумент last е false, ще се премести в началото.

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

Вмъкване() задава позицията, която трябва да се вмъкне, като първи аргумент, и елемента, който трябва да се вмъкне, като втори аргумент.

В примера към оригиналната променлива се присвоява нов обект, а към самия оригинален обект не се добавят нови елементи.

Пренареждане (пренареждане) на елементи

Замяната на елементи е същият процес като в примера по-горе.

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

Сортиране на елементи по ключ или стойност

Създаване на списък с кортежи (key, value) от подредени двойки ключ-стойност въз основа на обекта на изгледа, който може да бъде получен чрез метода items(), и предаването му на конструктора collections.OrderedDict() за създаване на нов обект.

Сортирането се извършва чрез задаване на анонимна функция (ламбда израз), която връща ключ или стойност от кортеж (ключ, стойност) като аргумент ключ на вградената функция sorted().

Ако искате да обърнете реда, задайте аргумента reverse на 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)])