Zarówno Python dict
(przed Pythonem 3.7), jak i obiekt JSON są kolekcjami nieuporządkowanymi. Możesz podać sort_keys
parametr, aby posortować klucze:
>>> 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}'
Jeśli potrzebujesz konkretnego zamówienia; możesz użyćcollections.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}'
Od Pythona 3.6 kolejność argumentów słów kluczowych jest zachowana, a powyższe można przepisać przy użyciu ładniejszej składni:
>>> json.dumps(OrderedDict(a=1, b=2))
'{"a": 1, "b": 2}'
>>> json.dumps(OrderedDict(b=2, a=1))
'{"b": 2, "a": 1}'
Patrz PEP 468 - Zachowywanie kolejności argumentów słów kluczowych .
Jeśli twoje dane wejściowe są podane jako JSON, a następnie, aby zachować kolejność (do pobrania OrderedDict
), możesz przejść object_pair_hook
, zgodnie z sugestią @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()
, możesz przekazaćdict
doOrderedDict()
, możesz również przekazać listę uporządkowanych pardict()
- chociaż kolejność jest tracona w obu tych przypadkach.ordereddict_literals
zcodetransformer
pakietu (jakość alfa)d = json.load(f, object_pairs_hook=OrderedDict)
, późniejjson.dump(d)
zachowa kolejność oryginalnych elementów.Jak wspominali inni, ta podstawowa zasada jest nieuporządkowana. Jednak w Pythonie istnieją obiekty OrderedDict. (Są wbudowane w najnowsze Pythony lub możesz użyć tego: http://code.activestate.com/recipes/576693/ ).
Uważam, że nowsze implementacje json w Pythonie poprawnie obsługują wbudowane w OrderedDicts, ale nie jestem pewien (i nie mam łatwego dostępu do testów).
Stare implementacje Pythona, simpleejson, nie obsługują ładnie obiektów OrderedDict ... i konwertują je na zwykłe dykty przed ich wyświetleniem ... ale możesz to obejść, wykonując następujące czynności:
teraz używając tego otrzymujemy:
Co jest prawie zgodne z oczekiwaniami.
Inną alternatywą byłoby wyspecjalizowanie kodera do bezpośredniego używania twojej klasy wiersza, a wtedy nie potrzebujesz żadnego pośredniego dyktu lub UnorderedDict.
źródło
sort_keys
sięTrue
podczas rozmowyjson.dumps()
; dla stabilności zamówienia (do testowania, stabilnego buforowania lub zatwierdzeń VCS) wystarczy sortowanie kluczy.Kolejność słownika nie ma żadnego związku z kolejnością, w jakiej został zdefiniowany. Dotyczy to wszystkich słowników, nie tylko tych, które zostały zamienione na JSON.
Rzeczywiście, słownik został przewrócony „do góry nogami”, zanim jeszcze dotarł
json.dumps
:źródło
hej, wiem, że jest już za późno na tę odpowiedź, ale dodaj sort_keys i przypisz do niej false w następujący sposób:
to działało dla mnie
źródło
json.dump () zachowa porządek w Twoim słowniku. Otwórz plik w edytorze tekstu, a zobaczysz. Zachowa porządek niezależnie od tego, czy wyślesz mu OrderedDict.
Ale json.load () utraci kolejność zapisanego obiektu, chyba że powiesz mu, aby załadował się do OrderedDict (), co jest wykonywane za pomocą parametru object_pairs_hook zgodnie z instrukcją JFSebastian powyżej.
W przeciwnym razie straciłby zamówienie, ponieważ podczas zwykłej operacji ładuje zapisany obiekt słownika do zwykłego dyktu, a zwykły dykt nie zachowuje oderu pozycji, które otrzymał.
źródło
w JSON, podobnie jak w JavaScript, kolejność kluczy obiektów jest bez znaczenia, więc tak naprawdę nie ma znaczenia, w jakiej kolejności są wyświetlane, jest to ten sam obiekt.
źródło
dict
)