Qual é a maneira correta de inicializar um dicionário ordenado (OD) para manter a ordem dos dados iniciais?
from collections import OrderedDict
# Obviously wrong because regular dict loses order
d = OrderedDict({'b':2, 'a':1})
# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b',2), ('a', 1)])
# What about using a list comprehension, will 'd' preserve the order of 'l'
l = ['b', 'a', 'c', 'aa']
d = OrderedDict([(i,i) for i in l])
Questão:
Uma
OrderedDict
preserva a ordem de uma lista de tuplas, ou tupla de tuplas ou tupla de listas ou lista de listas etc., passada no momento da inicialização (segundo e terceiro exemplo acima)?Como se verifica se
OrderedDict
realmente mantém um pedido? Como adict
possui uma ordem imprevisível, e se meus vetores de teste tiverem, felizmente, a mesma ordem inicial que a ordem imprevisível de um ditado? Por exemplo, se em vez ded = OrderedDict({'b':2, 'a':1})
escreverd = OrderedDict({'a':1, 'b':2})
, posso concluir erroneamente que a ordem está preservada. Nesse caso, descobri que adict
é ordenado alfabeticamente, mas isso nem sempre é verdade. Qual é uma maneira confiável de usar um contraexemplo para verificar se uma estrutura de dados preserva a ordem ou não, exceto por tentar vetores de teste repetidamente até que um deles se quebre?
PS: Vou deixar isso aqui apenas para referência : "O construtor OrderedDict e o método update () aceitam argumentos de palavras-chave, mas sua ordem é perdida porque a função do Python chama argumentos de palavras-passe de semântica de passagem de semântica usando um dicionário regular não ordenado"
PPS: Felizmente, no futuro, o OrderedDict também preservará a ordem dos kwargs (exemplo 1): http://bugs.python.org/issue16991
OrderDict(b=2, a=1)
também é uma maneira adequada. Veja PEP 468 .Respostas:
O OrderedDict preservará qualquer pedido ao qual ele tenha acesso. A única maneira de passar dados ordenados para inicializar é passar uma lista (ou, geralmente, uma iterável) de pares de valores-chave, como nos dois últimos exemplos. Como diz a documentação à qual você vinculou, o OrderedDict não tem acesso a nenhum pedido quando você passa argumentos de palavras-chave ou dict, pois qualquer pedido é removido antes que o construtor OrderedDict o veja.
Observe que o uso de uma compreensão de lista em seu último exemplo não muda nada. Não há diferença entre
OrderedDict([(i,i) for i in l])
eOrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c'), ('aa', 'aa')])
. A compreensão da lista é avaliada e cria a lista e é transmitida; OrderedDict não sabe nada sobre como foi criado.fonte
Sim, isso vai funcionar. Por definição, uma lista é sempre ordenada da maneira como é representada. Isso vale também para a compreensão da lista, a lista gerada é da mesma maneira que os dados foram fornecidos (ou seja, a fonte de uma lista será determinística, originada de uma quantidade
set
oudict
não muito).Você mantém sua lista de fontes com 2 tuplas para referência e as usa como dados de teste para seus casos de teste ao realizar testes de unidade. Faça uma iteração entre eles e garanta que o pedido seja mantido.
fonte
__hash__
. Especificamente sobre ostr
tipo.OrderedDict
para que eu não tenha a sobrecarga de converter uma lista em umOrderedDict
. Eu apenas percorro os elementos como uma lista em vez de um dicionário.