Ok, więc mogę użyć OrDERDict w json.dump
. Oznacza to, że OrdictDict może być użyty jako dane wejściowe do JSON.
Ale czy można go wykorzystać jako wynik? Jeśli tak to jak? W moim przypadku chciałbym przejść load
do nakazu, aby móc zachować kolejność kluczy w pliku.
Jeśli nie, czy istnieje jakieś obejście?
python
json
load
ordereddictionary
c00kiemonster
źródło
źródło
json.load
aby używać OrdersDicts zamiast Dicts w Pythonie.Odpowiedzi:
Tak, możesz. Podając
object_pairs_hook
argument JSONDecoder . W rzeczywistości jest to dokładny przykład podany w dokumentacji.Możesz przekazać ten parametr do
json.loads
(jeśli nie potrzebujesz instancji dekodera do innych celów):Korzystanie
json.load
odbywa się w ten sam sposób:źródło
object_pairs_hook
, zamiast „każda para zostanie przekazana do object_pairs_hook,”json.load
domyślnie nie zachowuje kolejności, ale wygląda na to, że odzwierciedla tylko to, co robi sam Json -{}
są nieuporządkowane, ale[]
w Json są uporządkowane zgodnie z opisem tutajOrderedDict
zostanie użyty do zbudowania wynikowej wartości pytona.Prosta wersja dla Python 2.7+
Lub dla Python 2.4 do 2.6
źródło
simplejson
iordereddict
są to osobne biblioteki, które musisz zainstalować.loads('{}', object_pairs_hook=OrderedDict)
.Kilka świetnych wiadomości! Od wersji 3.6 implementacja cPython zachowała kolejność wstawiania słowników ( https://mail.python.org/pipermail/python-dev/2016-September/146327.html ). Oznacza to, że biblioteka json domyślnie zachowuje teraz porządek. Zwróć uwagę na różnicę w zachowaniu między Pythonem 3.5 i 3.6. Kod:
W py3.5 wynikowa kolejność jest niezdefiniowana:
W implementacji cPython Pythona 3.6:
Naprawdę świetną wiadomością jest to, że stała się specyfikacją języka od Pythona 3.7 (w przeciwieństwie do szczegółów implementacji cPython 3.6+): https://mail.python.org/pipermail/python-dev/2017-December/151283 .html
Odpowiedź na twoje pytanie brzmi teraz: uaktualnij do Pythona 3.6! :)
źródło
json.loads('{"2": 2, "1": 1}')
staje się{'1': 1, '2': 2}
dla mnie.dict.__repr__
sortuje klucze, podczas gdy podstawowe porządkowanie jest zachowane. Innymi słowy,json.loads('{"2": 2, "1": 1}').items()
jestdict_items([('2', 2), ('1', 1)])
nawet jeślirepr(json.loads('{"2": 2, "1": 1}'))
jest"{'1': 1, '2': 2}"
.Zawsze możesz wypisać listę kluczy oprócz zrzucenia dykta, a następnie zrekonstruować je
OrderedDict
poprzez iterację po liście?źródło
OrdereDict
s.Oprócz zrzucania uporządkowanej listy kluczy obok słownika, innym rozwiązaniem o niskiej technologii, które ma tę zaletę, że jest jawne, jest zrzucenie (uporządkowanej) listy par klucz-wartość
ordered_dict.items()
; ładowanie jest prosteOrderedDict(<list of key-value pairs>)
. To obsługuje uporządkowany słownik, mimo że JSON nie ma tej koncepcji (słowniki JSON nie mają kolejności).Naprawdę miło jest skorzystać z faktu, że
json
zrzuty OragedDict są wykonywane we właściwej kolejności. Jednak generalnie niepotrzebnie ciężkie i niekoniecznie sensowne jest czytanie wszystkich słowników JSON jako OrDERDict (poprzezobject_pairs_hook
argument), więc sensowna jest także wyraźna konwersja tylko słowników, które należy zamówić.źródło
Zwykle używane polecenie ładowania zadziała, jeśli podasz parametr hook_pairs_hook :
źródło