Olykor szükség lehet arra, hogy egy szótárobjektumban az elemek (kulcs-érték párok) megőrizzék a bevitel szerinti sorrendjüket. A dict típusú szótár sokáig nem volt sorrendtartó, helyette a collections modul OrderedDict típusát kellett használni. A Python 3.7 verziótól azonban már a dict is megőrzi az elemek sorrendjét, sőt a Python 3.8 verziótól a reversed() függvénnyel is használható, hasonlóan az OrderedDict-hez. Ezért kérdésként merülhet fel, hogy van-e létjogosultsága még az OrderedDict típus használatának.
Az OrderedDict jelentősége valóban csökkent, de a Python 3.7-nél korábbi verziókban írt kódokkal való kompatibilitás biztosításán túl is azért maradt még néhány olyan jellemzője, amely adott esetben jól jöhet, mert egyszerűsítheti, illetve olvashatóbbá teheti a kódot:
– Ellentétben a dict szótárral az OrderedDict rendelkezik a move_to_end(key, last=True) metódussal, amely az első argumentumként megadott kulccsal rendelkező elemet vagy az utolsó helyre teszi, vagy az első helyre attól függően, hogy a metódus második, last nevű paramétere True vagy False értékű.
– A dict esetében is létező popitem() metódushoz képest, amely LIFO sorrendben távolít el egy elemet, az OrderDict popitem(last=True) metódusa FIFO sorrendben is képes erre, ha a metódus argumentuma False.
– A dict esetében is létező popitem() metódushoz képest, amely LIFO sorrendben távolít el egy elemet, az OrderDict popitem(last=True) metódusa FIFO sorrendben is képes erre, ha a metódus argumentuma False.
Szemléltető példaként modellezzünk egy orvosi várótermet az OrderDict objektummal, ahová különféle panaszokkal jönnek a betegek, akik magukkal hozzák a labor- vagy szűrővizsgálatuk eredményét. Az orvos alapvetően érkezési sorrendben fogadja a betegeket, de ha vannak lázasak, őket előrébb veszi. Az így kialakult sorrendben aztán egymás után behívja őket mindaddig míg van beteg a váróban. Az aktuálisan vizsgált beteg leletének pozitív vagy negatív eredménye alapján mond véleményt.
A modellt megvalósító program kódja alább látható. Ebben mind a move_to_end(), mind a popitem() metódusokat kihasználtuk.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
from collections import OrderedDict, namedtuple from enum import Enum Beteg = namedtuple('Beteg', 'név panasz') LeletEredmény = Enum('LeletEredmény', 'POZITÍV NEGATÍV') Lelet = namedtuple('Lelet', 'eredmény', defaults=(LeletEredmény.NEGATÍV,)) beérkező_betegek = [(Beteg('Tóth Géza', 'köhögés'), Lelet(LeletEredmény.POZITÍV)), (Beteg('Kiss Ilona', 'asztma'), Lelet(LeletEredmény.POZITÍV)), (Beteg('Réti Tibor', 'láz'), Lelet()), (Beteg('Kovács Ella', 'fejfájás'), Lelet()), (Beteg('Nagy Nándor', 'láz'), Lelet(LeletEredmény.POZITÍV))] # A váróterem megtelik az egymás után érkező betegekkel. váróterem = OrderedDict(beérkező_betegek) # Az orvos előre veszi a lázas betegeket. lázas_betegek = [beteg for beteg in váróterem if beteg.panasz == 'láz'] for lázas_beteg in reversed(lázas_betegek): # A reversed() azért kell, hogy a lázas betegek között is # megmaradjon az érkezési sorrend az alábbi előresorolás után is. váróterem.move_to_end(lázas_beteg, last=False) # Addig hívja be az orvos a betegeket sorban egymás után, amíg van beteg a váróban. while váróterem: # A váróteremből a sorrendben első, lelettel rendelkező beteg kihívása. beteg, lelet = váróterem.popitem(last=False) # A lelet áttanulmányozása és a következtetés közlése. if lelet.eredmény == LeletEredmény.NEGATÍV: következtetés = 'aggodalomra nincs ok' else: következtetés = 'további kezelés szükséges' print(f'Kedves {beteg.név}, a lelete alapján {következtetés}.') # Eredmény: # Kedves Réti Tibor, a lelete alapján aggodalomra nincs ok. # Kedves Nagy Nándor, a lelete alapján további kezelés szükséges. # Kedves Tóth Géza, a lelete alapján további kezelés szükséges. # Kedves Kiss Ilona, a lelete alapján további kezelés szükséges. # Kedves Kovács Ella, a lelete alapján aggodalomra nincs ok. |
A Python tudásépítés lépésről lépésre című e-könyvben mind az OrderDict, mind a példaprogramban használt egyéb nyelvi elemek részleteiben is ismertetve vannak.