dict를 OrderedDict로 변환


138

collections.OrderedDict수업 사용에 문제가 있습니다. Raspberry Pi의 데비안 배포판 인 Raspbian에서 Python 2.7을 사용하고 있습니다. 텍스트 어드벤처를 나란히 비교하기 위해 두 개의 사전을 인쇄하려고합니다. 순서는 정확하게 비교하기 위해 필수적입니다. 내가 무엇을 시도하더라도 사전은 일반적인 순서대로 인쇄됩니다.

내 RPi에서 할 때 얻을 수있는 내용은 다음과 같습니다.

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)])

분명히 함수 호출을 인쇄하고 키와 값 그룹을 중첩 된 목록에 넣기 때문에 옳지 않은 것이 있습니다 ...

이것은 내 PC에서 비슷한 것을 실행하여 얻은 것입니다.

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')])

이번에는 순서가 맞지만 다른 것을 올바르게 인쇄해서는 안됩니까? (목록에 넣고 함수 호출을 보여줍니다.)

오류는 어디에서 발생합니까? 파이썬의 파이 버전과는 아무런 관련이 없습니다. 파이썬은 단지 리눅스 버전이기 때문입니다.


3
참고 : OrderedDict영숫자 키 순서가 아닌 삽입 순서에 따라 정렬됩니다.
el.pescado

답변:


214

당신은 사전을 만드는 첫번째 다음에 그 사전을 전달 OrderedDict. Python 버전 <3.6 (*)의 경우 그렇게 할 때 순서가 더 이상 정확하지 않습니다. dict본질적으로 주문되지 않습니다.

대신 튜플 시퀀스를 전달하십시오.

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

인쇄 할 때 표시 되는 OrderedDict것은 표현 이며 완전히 정확합니다. OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])단지 재현 가능한 표현으로 내용이 무엇인지 보여줍니다 OrderedDict.


(*) : CPython 3.6 구현에서 dict형식은 삽입 순서를 유지하는 데 따른 부작용이있는 메모리 효율적인 내부 구조를 사용하도록 업데이트되었으며, 질문에 표시된 코드는 문제없이 작동합니다. Python 3.7부터 Python 언어 사양 이 업데이트되어 모든 Python 구현이이 동작을 따라야합니다. 자세한 내용과 특정 사례에 여전히을 사용하려는 이유 는이 다른 답변을 참조하십시오 OrderedDict().


그래서 OrderedDict가 사전을 만들 것입니까? 또한 재현 가능한 표현없이 인쇄하려면 OrderedDict 변수가 인쇄되어 있습니까? 즉 : print ship ?? 감사합니다 :)
pythonpiboy 2016 년

3
질문 : 당신이 설명한 방식으로, OrderedDict는 순서화 된 "목록"을 만들고 있습니다. 그것이 목적을 무너 뜨리지 않습니까? 그것은 키와 값을 가진 사전이 아닌 요소의 목록을 만들고 있습니다.
pythonpiboy

9
유형은 둘 다처럼 작동합니다. 순서를 유지하는 매핑 순서대로 하나를 만들려면 순서대로 항목을 제공해야합니다 . 표준 dict (PyPI 또는 Python 3.6 이상 이외의 것)에서는 그렇게 할 수 없으므로 대신 튜플 목록을 제공하십시오. 가되면 OrderedDict됩니다 만든 그것은 입니다 사전.
Martijn Pieters

4
혼란스러워 보이는 것은 OrderedDict가 단순히 주문을 유지하는 것이 아니라 주문을 "적용"한다고 가정하는 것입니다. 필자는 생성시 입력을 정렬한다고 가정했습니다. 또는 items () 함수는 정렬 된 항목을 삽입 시점과 상관없이 반환합니다. 대신 주문한 내용을 그대로 유지합니다.
whiterook6

2
@ whiterook6 : 정렬 된 사전이 아닙니다. 키-값 쌍의 순서를 기록하고 해당 쌍을 재정렬 할 수있는 사전 인 정렬 된 사전입니다. 이 순서를 순서대로 나열한 목록과 비교하십시오 .
Martijn Pieters

36

dict이 정의 된 코드의이 부분을 편집 할 수없는 경우 원하는 방식으로 언제든지 다음과 같이 주문할 수 있습니다.

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

ASC와 같은 일반적인 주문이 아닌 맞춤 주문이 필요한 경우 대부분 OrderedDict로 이동합니다.

제안 된 해결책은 다음과 같습니다.

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

출력됩니다 :

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

참고 : 새로운 정렬 된 사전은 항목이 삭제 될 때 정렬 순서를 유지합니다. 그러나 새 키가 추가되면 키가 끝에 추가되고 정렬이 유지되지 않습니다. ( official doc )


2

dict.items ()를 사용하십시오. 다음과 같이 간단 할 수 있습니다.

ship = collections.OrderedDict(ship.items())
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.