Os dicionários Python (objectos de tipo dict) não preservam a ordem dos elementos; CPython fá-lo desde 3.6, mas é dependente da implementação e indefinido noutras implementações; a especificação da linguagem tem preservado a ordem desde 3.7.
OrderedDict é fornecido no módulo de colecções da biblioteca padrão como um dicionário que preserva a encomenda. É seguro utilizar este.
Importar o módulo de colecções. Está incluído na biblioteca padrão e não necessita de ser instalado.
import collections
Se escrever o seguinte, pode omitir as colecções. nos exemplos seguintes.
from collections import OrderedDict
Segue-se uma descrição de como utilizar o OrderedDict.
- Criação de um objecto OrderedDict
- OrderedDict é uma subclasse de ditado
- Mover elementos para o início ou fim
- Acrescentar um novo elemento em qualquer posição.
- Reordenar (reordenar) elementos
- Classificar elementos por chave ou valor
Criação de um objecto OrderedDict
As colecções do construtor.OrderedDict() podem ser usadas para criar um objecto OrderedDict.
Criar um objecto OrderedDict vazio e acrescentar valores.
od = collections.OrderedDict()
od['k1'] = 1
od['k2'] = 2
od['k3'] = 3
print(od)
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
Também é possível especificar argumentos para o construtor.
Pode usar argumentos de palavras-chave, sequências de pares de valores-chave (tais como tuplos (chave, valor), etc.), e assim por diante. Este último pode ser uma lista ou um tuple, desde que seja um par de chaves de valor.
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)])
Até à versão 3.5, a ordem dos argumentos da palavra-chave não era preservada, mas desde a versão 3.6, é agora preservada.
Alterado na versão 3.6: Com a aceitação da PEP 468, a ordem do construtor do OrderedDict e os argumentos da palavra-chave passados para o método update() são preservados.
collections — Container datatypes — Python 3.10.0 Documentation
Os dicionários normais (objectos do tipo dict) também podem ser passados ao construtor, mas no caso de implementações onde o tipo dict não preserva a ordem, o OrderedDict gerado a partir dele também não irá preservar a ordem.
print(collections.OrderedDict({'k1': 1, 'k2': 2, 'k3': 3}))
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
OrderedDict é uma subclasse de ditado
OrderedDict é uma subclasse de ditame.
print(issubclass(collections.OrderedDict, dict))
# True
OrderedDict também tem os mesmos métodos que dict, e os métodos para obter, alterar, adicionar e remover elementos são os mesmos que 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)])
Ver o artigo seguinte para mais detalhes.
- Artigos relacionados:Acrescentar elementos a um dicionário e juntar dicionários em Python
Mover elementos para o início ou fim
Pode usar o método próprio do OrderedDict move_to_end() para mover um elemento para o início ou para o fim.
Especificar a chave como o primeiro argumento. O padrão é passar para o fim, mas se o segundo argumento for falso, será passado para o início.
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)])
Acrescentar um novo elemento em qualquer posição.
É possível criar um novo objecto OrderedDict com um novo elemento acrescentado a uma posição arbitrária. Especificamente, isto pode ser feito no fluxo seguinte.
- Listar os objectos de visualização que podem ser obtidos com o método items() usando a lista().
- Acrescentar um tuple (chave, valor) de pares chave-valor no método insert() da lista
- Criar um novo objecto passando-o para as colecções do construtor. 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() especifica a posição a ser inserida como o primeiro argumento, e o elemento a ser inserido como o segundo argumento.
No exemplo, um novo objecto é atribuído à variável original, e nenhum elemento novo é adicionado ao próprio objecto original.
Reordenar (reordenar) elementos
A substituição de elementos é o mesmo processo que no exemplo acima.
- Listar os objectos de visualização que podem ser obtidos com o método items() usando a lista().
- Substituir elementos numa lista
- Criar um novo objecto passando-o para as colecções do construtor. 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 quiser especificar uma chave e substituí-la, utilize o método index() para obter o índice (posição) da lista de chaves, como se mostra abaixo.
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)])
Classificar elementos por chave ou valor
Criar uma lista de tuplos (chave, valor) de pares de valores chave ordenados com base no objecto de visualização que pode ser obtido pelo método dos itens(), e passá-lo para as colecções do construtor.OrderedDict() para criar um novo objecto.
A ordenação é executada especificando uma função anónima (expressão lambda) que retorna uma chave ou valor de um tuple (chave, valor) como chave de argumento da função integrada ordenada().
Se quiser inverter a ordem, defina o argumento inverso de classificado() para verdadeiro.
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)])