Ok, então eu posso usar um OrderedDict no json.dump
. Ou seja, um OrderedDict pode ser usado como uma entrada para JSON.
Mas pode ser usado como saída? Se sim, como? No meu caso, gostaria de load
inserir um OrderedDict para manter a ordem das chaves no arquivo.
Caso contrário, existe algum tipo de solução alternativa?
python
json
load
ordereddictionary
c00kiemonster
fonte
fonte
json.load
registro para usar OrderedDicts em vez de Dicts em Python.Respostas:
Sim você pode. Especificando o
object_pairs_hook
argumento para JSONDecoder . De fato, este é o exemplo exato fornecido na documentação.Você pode passar esse parâmetro para
json.loads
(se você não precisar de uma instância de decodificador para outros fins) da seguinte forma:O uso
json.load
é feito da mesma maneira:fonte
object_pairs_hook
, em vez de "cada par será passado para object_pairs_hook,"json.load
não mantê-lo ordenados por padrão, mas parece que é apenas um reflexo do que json em si faz - o{}
são não-ordenada, mas o[]
no json são ordenados conforme descrito aquiOrderedDict
será usado para criar o valor python resultante.Versão simples para Python 2.7+
Ou para Python 2.4 a 2.6
fonte
simplejson
eordereddict
são bibliotecas separadas que você precisa instalar.loads('{}', object_pairs_hook=OrderedDict)
.Boas notícias! Desde a versão 3.6, a implementação do cPython preservou a ordem de inserção dos dicionários ( https://mail.python.org/pipermail/python-dev/2016-September/146327.html ). Isso significa que a biblioteca json agora está preservando a ordem por padrão. Observe a diferença de comportamento entre o python 3.5 e 3.6. O código:
No py3.5, a ordem resultante é indefinida:
Na implementação cPython do python 3.6:
A boa notícia é que isso se tornou uma especificação de linguagem a partir do python 3.7 (em oposição a um detalhe de implementação do cPython 3.6+): https://mail.python.org/pipermail/python-dev/2017-December/151283 .html
Portanto, a resposta para sua pergunta agora é: atualize para python 3.6! :)
fonte
json.loads('{"2": 2, "1": 1}')
se torna{'1': 1, '2': 2}
para mim.dict.__repr__
chaves de classificação enquanto a ordem subjacente é preservada. Em outras palavras,json.loads('{"2": 2, "1": 1}').items()
édict_items([('2', 2), ('1', 1)])
mesmo serepr(json.loads('{"2": 2, "1": 1}'))
é"{'1': 1, '2': 2}"
.Você sempre pode escrever a lista de chaves, além de despejar o dict e, em seguida, reconstruí-lo
OrderedDict
iterando pela lista?fonte
OrdereDict
s.Além de descartar a lista ordenada de chaves ao lado do dicionário, outra solução de baixa tecnologia, que tem a vantagem de ser explícita, é despejar a lista (ordenada) de pares de valores-chave
ordered_dict.items()
; o carregamento é simplesOrderedDict(<list of key-value pairs>)
. Isso lida com um dicionário ordenado, apesar do JSON não ter esse conceito (os dicionários JSON não têm ordem).É realmente bom aproveitar o fato de que
json
despeja o OrderedDict na ordem correta. No entanto, em geral é desnecessariamente pesado e não necessariamente significativo ter que ler todos os dicionários JSON como um OrderedDict (por meio doobject_pairs_hook
argumento); portanto, uma conversão explícita apenas dos dicionários que devem ser ordenados também faz sentido.fonte
O comando de carregamento normalmente usado funcionará se você especificar o parâmetro object_pairs_hook :
fonte