Jak używać OrderedDict, uporządkowanego słownika Pythona.

Biznes

Słowniki Pythona (obiekty typu dict) nie zachowują kolejności elementów; CPython robi to od 3.6, ale jest to zależne od implementacji i nieokreślone w innych implementacjach; specyfikacja języka zachowuje kolejność od 3.7.

OrderedDict jest dostarczany w module kolekcji biblioteki standardowej jako słownik, który zachowuje kolejność. Bezpiecznie jest używać właśnie tego.

Zaimportuj moduł kolekcji. Jest on zawarty w bibliotece standardowej i nie musi być instalowany.

import collections

Jeśli piszesz to, co poniżej, możesz pominąć kolekcje. w następujących przykładach.

from collections import OrderedDict

Poniżej znajduje się opis jak używać OrderedDict.

  • Tworzenie obiektu OrderedDict
  • OrderedDict jest podklasą klasy dict
  • Przesuń elementy na początek lub koniec
  • Dodaj nowy element w dowolnym miejscu.
  • Zmiana układu (kolejności) elementów
  • Sortuj elementy według klucza lub wartości

Tworzenie obiektu OrderedDict

Konstruktor collections.OrderedDict() może być użyty do stworzenia obiektu OrderedDict.

Utworzenie pustego obiektu OrderedDict i dodanie wartości.

od = collections.OrderedDict()

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

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

Możliwe jest również podanie argumentów do konstruktora.

Możesz używać argumentów słów kluczowych, sekwencji par klucz-wartość (takich jak tuple (klucz, wartość)), i tak dalej. Te ostatnie mogą być listą lub tuple, o ile są parą klucz-wartość.

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

Do wersji 3.5 kolejność argumentów słów kluczowych nie była zachowywana, ale od wersji 3.6 jest już zachowana.

Zmienione w wersji 3.6: Wraz z akceptacją PEP 468, zachowana została kolejność konstruktora OrderedDict oraz argumentów słów kluczowych przekazywanych do metody update().
collections — Container datatypes — Python 3.10.0 Documentation

Do konstruktora można również przekazać zwykłe słowniki (obiekty typu dict), jednak w przypadku implementacji, w których typ dict nie zachowuje porządku, wygenerowany z niego OrderedDict również nie będzie zachowywał porządku.

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

OrderedDict jest podklasą klasy dict

OrderedDict jest podklasą klasy dict.

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

OrderedDict posiada również te same metody co dict, a metody pobierania, zmiany, dodawania i usuwania elementów są takie same jak 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)])

Zobacz poniższy artykuł, aby poznać szczegóły.

Przesuń elementy na początek lub koniec

Możesz użyć własnej metody OrderedDict move_to_end(), aby przesunąć element na początek lub koniec.

Jako pierwszy argument podaj klucz. Domyślnie zostanie przeniesiony na koniec, ale jeśli drugi argument last jest fałszywy, zostanie przeniesiony na początek.

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

Dodaj nowy element w dowolnym miejscu.

Możliwe jest stworzenie nowego obiektu OrderedDict z nowym elementem dodanym w dowolnym miejscu. Konkretnie można to zrobić w następujący sposób.

  1. Wylistuj obiekty widoku, które można uzyskać za pomocą metody items() używając list().
  2. Dodaj tuple (klucz, wartość) par klucz-wartość w metodzie insert() listy
  3. Utwórz nowy obiekt, przekazując go do konstruktora 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() podaje jako pierwszy argument pozycję do wstawienia, a jako drugi argument element do wstawienia.

W przykładzie nowy obiekt jest przypisany do oryginalnej zmiennej, a do samego oryginalnego obiektu nie są dodawane żadne nowe elementy.

Zmiana układu (kolejności) elementów

Wymiana elementów odbywa się w taki sam sposób jak w powyższym przykładzie.

  1. Wylistuj obiekty widoku, które można uzyskać za pomocą metody items() używając list().
  2. Zamień elementy na liście
  3. Utwórz nowy obiekt, przekazując go do konstruktora 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)])

Jeśli chcesz określić klucz i go zastąpić, użyj metody index(), aby uzyskać indeks (pozycję) z listy kluczy, jak pokazano poniżej.

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

Sortuj elementy według klucza lub wartości

Tworzy listę tupli (klucz, wartość) posortowanych par klucz-wartość na podstawie obiektu widoku, który można uzyskać za pomocą metody items() i przekazuje ją do konstruktora collections.OrderedDict() w celu utworzenia nowego obiektu.

Sortowanie odbywa się poprzez określenie anonimowej funkcji (wyrażenie lambda), która zwraca klucz lub wartość z tupli (klucz, wartość) jako argument klucz wbudowanej funkcji sorted().

Jeśli chcesz odwrócić kolejność, ustaw argument reverse funkcji sorted() na 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)])