Come usare OrderedDict, un dizionario ordinato in Python.

Attività commerciale

I dizionari Python (oggetti di tipo dict) non conservano l'ordine degli elementi; CPython lo fa dalla 3.6, ma è dipendente dall'implementazione e indefinito in altre implementazioni; la specifica del linguaggio conserva l'ordine dalla 3.7.

OrderedDict è fornito nel modulo collections della libreria standard come dizionario che conserva l'ordine. È sicuro usare questo.

Importa il modulo delle collezioni. È incluso nella libreria standard e non ha bisogno di essere installato.

import collections

Se scrivete quanto segue, potete omettere le collezioni. negli esempi seguenti.

from collections import OrderedDict

Quella che segue è una descrizione di come usare OrderedDict.

  • Creare un oggetto OrderedDict
  • OrderedDict è una sottoclasse di dict
  • Sposta gli elementi all'inizio o alla fine
  • Aggiungere un nuovo elemento in qualsiasi posizione.
  • Riorganizzare (riordinare) gli elementi
  • Ordina gli elementi per chiave o valore

Creare un oggetto OrderedDict

Il costruttore collections.OrderedDict() può essere usato per creare un oggetto OrderedDict.

Crea un oggetto OrderedDict vuoto e aggiunge valori.

od = collections.OrderedDict()

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

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

È anche possibile specificare degli argomenti al costruttore.

Potete usare argomenti di parole chiave, sequenze di coppie chiave-valore (come tuple (chiave, valore)), e così via. Quest'ultimo può essere una lista o una tupla, purché sia una coppia chiave-valore.

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

Fino alla versione 3.5, l'ordine degli argomenti delle parole chiave non era conservato, ma dalla versione 3.6, lo è ora.

Modificato nella versione 3.6: Con l'accettazione di PEP 468, l'ordine del costruttore di OrderedDict e degli argomenti delle parole chiave passate al metodo update() è conservato.
collections — Container datatypes — Python 3.10.0 Documentation

Anche i dizionari normali (oggetti di tipo dict) possono essere passati al costruttore, ma nel caso di implementazioni in cui il tipo dict non conserva l'ordine, anche l'OrderedDict generato da esso non conserva l'ordine.

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

OrderedDict è una sottoclasse di dict

OrderedDict è una sottoclasse di dict.

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

OrderedDict ha anche gli stessi metodi di dict, e i metodi per ottenere, cambiare, aggiungere e rimuovere elementi sono gli stessi di 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)])

Vedi il seguente articolo per i dettagli.

Sposta gli elementi all'inizio o alla fine

Potete usare il metodo di OrderedDict move_to_end() per spostare un elemento all'inizio o alla fine.

Specifica la chiave come primo argomento. L'impostazione predefinita è di spostare alla fine, ma se il secondo argomento ultimo è falso, verrà spostato all'inizio.

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

Aggiungere un nuovo elemento in qualsiasi posizione.

È possibile creare un nuovo oggetto OrderedDict con un nuovo elemento aggiunto in una posizione arbitraria. In particolare, questo può essere fatto nel seguente flusso.

  1. Elenca gli oggetti della vista che possono essere ottenuti con il metodo items() usando list().
  2. Aggiungere una tupla (chiave, valore) di coppie chiave-valore nel metodo insert() della lista
  3. Creare un nuovo oggetto passandolo al costruttore 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() specifica la posizione da inserire come primo argomento e l'elemento da inserire come secondo argomento.

Nell'esempio, un nuovo oggetto viene assegnato alla variabile originale, e nessun nuovo elemento viene aggiunto all'oggetto originale stesso.

Riorganizzare (riordinare) gli elementi

La sostituzione degli elementi è lo stesso processo dell'esempio precedente.

  1. Elenca gli oggetti della vista che possono essere ottenuti con il metodo items() usando list().
  2. Sostituire elementi in una lista
  3. Creare un nuovo oggetto passandolo al costruttore 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)])

Se volete specificare una chiave e sostituirla, usate il metodo index() per ottenere l'indice (posizione) dalla lista delle chiavi come mostrato qui sotto.

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

Ordina gli elementi per chiave o valore

Crea una lista di tuple (chiave, valore) di coppie chiave-valore ordinate basate sull'oggetto vista che può essere ottenuto dal metodo items(), e lo passa al costruttore collections.OrderedDict() per creare un nuovo oggetto.

L'ordinamento viene eseguito specificando una funzione anonima (espressione lambda) che restituisce una chiave o un valore da una tupla (chiave, valore) come argomento chiave della funzione built-in sorted().

Se volete invertire l'ordine, impostate l'argomento reverse di sorted() a 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)])