Chuyển đổi dict thành OrderedDict


138

Tôi đang gặp một số rắc rối khi sử dụng collections.OrderedDictlớp học. Tôi đang sử dụng Python 2.7 trên Raspbian, bản phân phối Debian cho Raspberry Pi. Tôi đang cố gắng in hai cuốn từ điển để so sánh (cạnh nhau) cho một cuộc phiêu lưu văn bản. Thứ tự là cần thiết để so sánh chính xác. Không có vấn đề gì tôi thử từ điển in theo cách không có thứ tự thông thường của họ.

Đây là những gì tôi nhận được khi thực hiện trên RPi của mình:

import collections

ship = {"NAME": "Albatross",
         "HP":50,
         "BLASTERS":13,
         "THRUSTERS":18,
         "PRICE":250}

ship = collections.OrderedDict(ship)

print ship
# OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])

Rõ ràng có điều gì đó không đúng bởi vì nó đang in lệnh gọi hàm và đưa các khóa và nhóm giá trị vào một danh sách lồng nhau ...

Đây là những gì tôi có được bằng cách chạy một cái gì đó tương tự trên PC của tôi:

import collections

Joe = {"Age": 28, "Race": "Latino", "Job": "Nurse"}
Bob = {"Age": 25, "Race": "White", "Job": "Mechanic", "Random": "stuff"}

#Just for clarity:
Joe = collections.OrderedDict(Joe)
Bob = collections.OrderedDict(Bob)

print Joe
# OrderedDict([('Age', 28), ('Race', 'Latino'), ('Job', 'Nurse')])
print Bob
# OrderedDict([('Age', 25), ('Race', 'White'), ('Job', 'Mechanic'), ('Random', 'stuff')])

Lần này, theo thứ tự, nhưng nó không nên in những thứ khác mặc dù phải không? (Việc đưa nó vào danh sách và hiển thị chức năng gọi.)

Tôi đang mắc lỗi ở đâu? Không nên làm gì với phiên bản pi của Python vì đây chỉ là phiên bản Linux.


2
Lưu ý: OrderedDictđược sắp xếp theo thứ tự chèn, không phải thứ tự phím chữ và số.
el.pescado

Câu trả lời:


214

Bạn đang tạo một từ điển trước , sau đó chuyển từ điển đó cho một OrderedDict. Đối với các phiên bản Python <3.6 (*) , tại thời điểm bạn thực hiện việc đó, việc đặt hàng sẽ không còn chính xác nữa. dictvốn dĩ không được đặt hàng.

Thay vào đó là một chuỗi các bộ dữ liệu thay thế:

ship = [("NAME", "Albatross"),
        ("HP", 50),
        ("BLASTERS", 13),
        ("THRUSTERS", 18),
        ("PRICE", 250)]
ship = collections.OrderedDict(ship)

Những gì bạn thấy khi bạn in OrderedDictđại diện của nó , và nó hoàn toàn chính xác. OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])chỉ cho bạn thấy, trong một đại diện có thể tái tạo , nội dung của là gì OrderedDict.


(*) : Trong việc thực hiện CPython 3.6, các dictloại đã được cập nhật để sử dụng một bộ nhớ hiệu quả hơn cấu trúc nội bộ mà có tác dụng phụ hạnh phúc của giữ gìn trật tự chèn, và bằng cách mở rộng mã hiển thị trong các công trình câu hỏi mà không vấn đề. Kể từ Python 3.7, đặc tả ngôn ngữ Python đã được cập nhật để yêu cầu tất cả các cài đặt Python phải tuân theo hành vi này. Xem câu trả lời khác này của tôi để biết chi tiết và lý do tại sao bạn vẫn có thể muốn sử dụng OrderedDict()cho một số trường hợp nhất định.


Ok vậy OrderedDict sẽ TẠO từ điển cho tôi? Ngoài ra, để in mà không có biểu diễn có thể lặp lại, tôi chỉ có thể in biến OrderedDict được sử dụng trong? tức là: print ship ?? Cảm ơn :)
pythonpiboy

3
Câu hỏi: Theo cách bạn mô tả, OrderedDict đang tạo một "danh sách" được đặt hàng. Điều đó không đánh bại mục đích? Nó chỉ tạo ra một danh sách các yếu tố, không phải từ điển với các khóa và giá trị ...
pythonpiboy

9
Các loại hoạt động như cả hai; một ánh xạ duy trì trật tự. Để tạo một thứ tự với thứ tự, bạn cần cung cấp cho nó các mục theo thứ tự . Vì một lệnh chính (trên bất kỳ thứ gì khác ngoài PyPI hoặc Python 3.6+) không thể làm điều đó, thay vào đó, bạn cung cấp cho nó một danh sách các bộ dữ liệu. Một khi OrderedDictđược tạo ra một từ điển.
Martijn Pieters

4
Âm thanh giống như sự nhầm lẫn là từ giả định OrderedDict "áp dụng" một đơn đặt hàng, thay vì chỉ giữ lại một đơn đặt hàng. Tôi chắc chắn giả định rằng nó sẽ sắp xếp đầu vào khi tạo - hoặc hàm items () sẽ trả về các mục được sắp xếp bất kể khi nào chúng được chèn. Thay vào đó, nó chỉ giữ bất cứ thứ gì bạn cung cấp.
whiterook6

2
@ whiterook6: nó không phải là một từ điển được sắp xếp . Đó là một từ điển được đặt hàng, một từ điển ghi lại thứ tự của các cặp khóa-giá trị và cho phép bạn sắp xếp lại các cặp đó. So sánh điều này với danh sách, được sắp xếp thứ tự .
Martijn Pieters

36

Nếu bạn không thể chỉnh sửa phần mã này khi xác định chính tả của bạn, bạn vẫn có thể đặt hàng tại bất kỳ điểm nào theo bất kỳ cách nào bạn muốn, như thế này:

from collections import OrderedDict

order_of_keys = ["key1", "key2", "key3", "key4", "key5"]
list_of_tuples = [(key, your_dict[key]) for key in order_of_keys]
your_dict = OrderedDict(list_of_tuples)

11

Hầu hết thời gian chúng tôi dành cho OrderedDict khi chúng tôi yêu cầu một đơn hàng tùy chỉnh không phải là chung chung như ASC, v.v.

Đây là giải pháp được đề xuất:

import collections
ship = {"NAME": "Albatross",
         "HP":50,
         "BLASTERS":13,
         "THRUSTERS":18,
         "PRICE":250}

ship = collections.OrderedDict(ship)

print ship


new_dict = collections.OrderedDict()
new_dict["NAME"]=ship["NAME"]
new_dict["HP"]=ship["HP"]
new_dict["BLASTERS"]=ship["BLASTERS"]
new_dict["THRUSTERS"]=ship["THRUSTERS"]
new_dict["PRICE"]=ship["PRICE"]


print new_dict

Đây sẽ là đầu ra:

OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])
OrderedDict([('NAME', 'Albatross'), ('HP', 50), ('BLASTERS', 13), ('THRUSTERS', 18), ('PRICE', 250)])

Lưu ý : Các từ điển được sắp xếp mới duy trì thứ tự sắp xếp của chúng khi các mục bị xóa. Nhưng khi các khóa mới được thêm vào, các khóa sẽ được thêm vào cuối và sắp xếp không được duy trì. (Tài liệu chính thức )


2

Sử dụng dict.items (); nó có thể đơn giản như sau:

ship = collections.OrderedDict(ship.items())
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.