O Python dict
(antes do Python 3.7) e o objeto JSON são coleções não ordenadas. Você pode passar o sort_keys
parâmetro para classificar as chaves:
>>> import json
>>> json.dumps({'a': 1, 'b': 2})
'{"b": 2, "a": 1}'
>>> json.dumps({'a': 1, 'b': 2}, sort_keys=True)
'{"a": 1, "b": 2}'
Se você precisar de um pedido específico; você poderia usarcollections.OrderedDict
:
>>> from collections import OrderedDict
>>> json.dumps(OrderedDict([("a", 1), ("b", 2)]))
'{"a": 1, "b": 2}'
>>> json.dumps(OrderedDict([("b", 2), ("a", 1)]))
'{"b": 2, "a": 1}'
Desde o Python 3.6 , a ordem dos argumentos das palavras-chave é preservada e as opções acima podem ser reescritas usando uma sintaxe melhor:
>>> json.dumps(OrderedDict(a=1, b=2))
'{"a": 1, "b": 2}'
>>> json.dumps(OrderedDict(b=2, a=1))
'{"b": 2, "a": 1}'
Consulte PEP 468 - Preservando a ordem dos argumentos das palavras-chave .
Se sua entrada é fornecida como JSON, para preservar o pedido (para obter OrderedDict
), você pode passar object_pair_hook
, conforme sugerido por @Fred Yankowski :
>>> json.loads('{"a": 1, "b": 2}', object_pairs_hook=OrderedDict)
OrderedDict([('a', 1), ('b', 2)])
>>> json.loads('{"b": 2, "a": 1}', object_pairs_hook=OrderedDict)
OrderedDict([('b', 2), ('a', 1)])
OrderedDict()
, você pode passardict
paraOrderedDict()
, você também pode passar uma lista de pares ordenadosdict()
- embora a ordem seja perdida nos dois casos.ordereddict_literals
partir docodetransformer
pacote (qualidade alfa)d = json.load(f, object_pairs_hook=OrderedDict)
, um posteriorjson.dump(d)
manterá a ordem dos elementos originais.Como outros já mencionaram, o ditado subjacente não é ordenado. No entanto, existem objetos OrderedDict em python. (Eles são construídos em pythons recentes, ou você pode usá-lo: http://code.activestate.com/recipes/576693/ ).
Acredito que as implementações mais recentes do pythons json lidem corretamente com o OrderedDicts, mas não tenho certeza (e não tenho acesso fácil para testar).
As implementações python antigas do simplejson não manipulam muito bem os objetos OrderedDict .. e os convertem em dict regulares antes de produzi-los .. mas você pode superar isso fazendo o seguinte:
agora usando isso, obtemos:
O que é praticamente o desejado.
Outra alternativa seria especializar o codificador para usar diretamente sua classe de linha e, portanto, você não precisaria de nenhum ditado intermediário ou UnorderedDict.
fonte
sort_keys
aTrue
quando chamadojson.dumps()
; para a estabilidade do pedido (para teste, armazenamento em cache estável ou confirmações VCS), basta selecionar as chaves.A ordem de um dicionário não tem relação com a ordem em que foi definida. Isso é verdade para todos os dicionários, não apenas para os que foram transformados em JSON.
De fato, o dicionário foi "virado de cabeça para baixo" antes mesmo de chegar a
json.dumps
:fonte
ei, eu sei que é muito tarde para esta resposta, mas adicione sort_keys e atribua false a ele da seguinte maneira:
isso funcionou para mim
fonte
json.dump () preservará a ordem do seu dicionário. Abra o arquivo em um editor de texto e você verá. Ele preservará o pedido, independentemente de você enviar um OrderedDict.
Mas json.load () perderá a ordem do objeto salvo, a menos que você solicite que ele carregue em um OrderedDict (), o que é feito com o parâmetro object_pairs_hook como o JFSebastian instruiu acima.
Caso contrário, ele perderia a ordem porque, sob operação usual, carrega o objeto de dicionário salvo em um ditado regular e um ditado regular não preserva a aparência dos itens fornecidos.
fonte
em JSON, como em Javascript, a ordem das chaves do objeto não faz sentido; portanto, não importa em que ordem elas são exibidas, é o mesmo objeto.
fonte
dict
)