Như những người khác đã nói, dict
là không có thứ tự. collections.OrderedDict
là lớp con dict có khóa được sắp xếp. Vấn đề là json.load
trả về một trực tiếp dict
và chúng tôi không thể ném kết quả theo số OrderedDict
vì thứ tự của các khóa đã bị mất thông tin trước thời điểm này.
Chúng ta cần một cách để nói json.load
để trả lại một OrderedDict
thay vì một dict
.Đây có thể được thực hiện bằng cách thực hiện một phong tục json.JSONDecoder
mà cung cấp một object_pairs_hook
. object_pairs_hook
được cung cấp một đối tượng JSON dưới dạng danh sách (key, value)
tuples theo thứ tự chúng xuất hiện trong tài liệu JSON. Nó sẽ trả về bản dịch của đối tượng này thành đối tượng Python. Chúng tôi sẽ đưa danh sách các bộ dữ liệu này tới bộ khởi tạo cho collections.OrderedDict
và điều đó sẽ thực hiện thủ thuật.
Dưới đây là một số mã:
data = """
{
"foo": "bar",
"a_list": [1, 2, 3],
"another_object": {
"c": 3,
"a": 1,
"b": 2
},
"last_key": 42
}
"""
decoder = json.JSONDecoder(object_pairs_hook=collections.OrderedDict)
result = decoder.decode(data)
print(result)
mang đến cho:
OrderedDict([('foo', 'bar'),
('a_list', [1, 2, 3]),
('another_object', OrderedDict([('c', 3), ('a', 1), ('b', 2)])),
('last_key', 42)])
Cuối cùng, bạn có thể tự hỏi: "tại sao là việc làm thêm rất nhiều này?". Vâng, JSON không được coi là một cấu trúc dữ liệu với bất kỳ thứ tự cố định nào. Bạn sẽ chống lại hạt bằng cách làm điều này.
Bạn có thể đọc nó bằng cách đối tượng, và khi bạn đọc từng đối tượng thêm một phím theo thứ tự. Tôi chưa bao giờ làm việc với JSON nhưng tôi sẽ tưởng tượng một cái gì đó như lần đầu tiên đọc tệp và sau đó lặp lại từng đối tượng và khi nó được chuyển đổi thành JSON thêm thuộc tính mới - thứ tự ban đầu – PyNEwbie
Đối tượng JSON là [theo định nghĩa] (http://www.json.org), "một tập hợp các cặp tên/giá trị không theo thứ tự". Bạn thực sự không nên sử dụng các đối tượng JSON (hoặc có lẽ bạn thậm chí không nên sử dụng JSON) nếu thứ tự mà trong đó các cặp khóa-giá trị được chỉ định ban đầu là quan trọng. –