2.37. Imenovane n-torke i dvostrani redovi¶
Liste, n-torke, rječnici i skupovi pokrivaju većinu potreba za podacima. Tri druga spremnika u modulu collections odgovaraju specifičnim problemima koje ugrađeni tipovi rješavaju nespretno.
2.37.1. namedtuple – tipizirani zapisi bez klase¶
Obična n-torka pohranjuje vrijednosti po poziciji. To je u redu za malu, kratkotrajnu n-torku s 2 ili 3 elementa, ali nakon toga point[0] i point[1] počinju lagati o tome što sadrže. collections.namedtuple() vraća novu podklasu n-torke čija polja imaju imena:
>>> from collections import namedtuple
>>> Reading = namedtuple('Reading', ('temp', 'humidity', 'ts'))
>>> r = Reading(22.5, 41.0, 137204)
>>> r.temp
22.5
>>> r.humidity
41.0
>>> r[0]
22.5
Argument polja je niz nizova imena (ili jedan niz razdvojen razmacima u CPythonu; MicroPython je stroži – proslijedite n-torku ili listu).
Zašto koristiti namedtuple umjesto klase?
To je n-torka. Iteracija, raspakiravanje, jednakost, raspršivanje i korištenje kao ključa rječnika – sve radi besplatno.
Nepromjenjiva je. Ponovno pridruživanje
r.temp = ...podižeAttributeError, što je upravo ono što želite za tip zapisa.Troši manje RAM-a nego instanca klase s istim poljima – pohrana n-torke je neprekinuta, bez
__dict__.
U usporedbi s istovrijednom klasom, deklaracija namedtuple je jedan redak. Kompromis je u tome što su polja samo za čitanje – da biste „promijenili” očitanje, izrađujete novo.
2.37.2. deque – ograničeni prstenasti međuspremnik¶
Lista je brza na kraju (append / pop) i spora na početku (insert(0, ...) / pop(0) oboje pomiču svaki drugi element). collections.deque je brz na oba kraja – to je prstenasti međuspremnik indeksiran pokazivačima na glavu i rep, pa dodavanje i uklanjanje na bilo kojoj strani izvode istu fiksnu količinu posla bez obzira na to koliko stavki deque sadrži.
Konstrukcija u MicroPythonu zahtijeva i početni iterabilni objekt i maksimalnu duljinu, tim redoslijedom:
>>> from collections import deque
>>> events = deque((), 5)
>>> for i in range(8):
... events.append(i)
>>> list(events)
[3, 4, 5, 6, 7]
Kada je ograničeni deque pun, svaki append izbacuje najstariju stavku. To čini deque idealnim za „posljednjih N uzoraka”, „posljednjih N redaka zapisnika” ili svaki klizni prozor koji ne treba rasti zauvijek.
Metode izložene na MicroPythonovom deque-u namjerno su minimalne:
append(x)– dodaj zdesna.appendleft(x)– dodaj slijeva.extend(iterable)– dodaj svaku stavku iz iterabilnog objekta.pop()– ukloni i vrati desni kraj. PodižeIndexErrorkada je prazan.popleft()– ukloni i vrati lijevi kraj.
Značajni izostanci iz CPythonovog deque-a: nema clear, count, index, remove, reverse, rotate, atributa maxlen ili __contains__. Iteracija i indeksiranje pretplaćivanjem rade:
>>> events[0]
3
>>> for e in events:
... print(e)
Tipična upotreba: zadržavanje posljednjih nekoliko očitanja senzora radi otkrivanja promjena trenda:
history = deque((), 10)
def push(reading):
history.append(reading)
if len(history) == 10 and history[-1] > 2 * history[0]:
print('reading is climbing')
2.37.3. OrderedDict – kada je redoslijed dio jednakosti¶
Obični dict čuva redoslijed umetanja od MicroPythona 1.13 i CPythona 3.7. To pokriva najčešći razlog zbog kojeg su ljudi nekoć posezali za collections.OrderedDict.
Što vam OrderedDict i dalje daje, a obični dict ne:
Jednakost kod
OrderedDictuzima u obzir redoslijed. Dva obična rječnika uspoređuju se kao jednaki kad god imaju iste parove ključ/vrijednost, bez obzira na redoslijed umetanja. Dvije instanceOrderedDictjednake su samo ako su im parovi istim redoslijedom:>>> from collections import OrderedDict >>> OrderedDict([('a', 1), ('b', 2)]) == OrderedDict([('b', 2), ('a', 1)]) False >>> {'a': 1, 'b': 2} == {'b': 2, 'a': 1} True
OrderedDictje koristan kada serijalizirate konfiguraciju u format kojemu jest stalo do redoslijeda ključeva (TOML, neki potrošači YAML-a) ili kada želite jasan dokumentacijski nagovještaj da je redoslijed bitan za čitatelje vašeg koda.
Za svakodnevni kod radije koristite ugrađeni dict. Posegnite za OrderedDict samo kada semantika redoslijed-je-dio-jednakosti ili dokumentacijska vrijednost stvarno nešto donosi.
Svaki od tri spremnika ima jednu usku namjenu. Imenovane n-torke zamjenjuju ručno izrađene klase zapisa; dvostrani redovi zamjenjuju liste za ograničene redove; uređeni rječnici čine redoslijed umetanja dijelom ugovora.