[python] 선언 된 것과 동일한 순서로 키 / 값을 유지하는 방법은 무엇입니까?

특정 순서로 선언 한 사전이 있고 항상 그 순서대로 유지하고 싶습니다. 키 / 값은 실제로 값을 기준으로 순서를 유지할 수 없으므로 선언 된 순서대로 원합니다.

사전이 있다면 :

d = {'ac': 33, 'gw': 20, 'ap': 102, 'za': 321, 'bs': 10}

그것을 보거나 반복하면 순서가 맞지 않습니다. 파이썬이 키 / 값을 선언 한 명시 적 순서를 유지할 수있는 방법이 있습니까?



답변

Python 3.6부터 표준 dict유형은 기본적으로 삽입 순서를 유지합니다.

정의

d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}

소스 코드에 나열된 순서대로 키가있는 사전이 생성됩니다.

이것은 희소 해시 테이블에 정수가있는 간단한 배열을 사용하여 달성되었습니다. 여기서 해당 정수는 키-값 쌍 (및 계산 된 해시)을 저장하는 다른 배열로 색인됩니다. 후자의 배열은 항목을 삽입 순서대로 저장하기 때문에 전체 조합은 실제로 Python 3.5 및 이전 버전에서 사용 된 구현보다 적은 메모리를 사용합니다. 자세한 내용은 Raymond Hettinger원본 아이디어 게시물 을 참조하십시오.

3.6에서 이것은 여전히 ​​구현 세부 사항으로 간주되었습니다. Python 3.6 설명서 의 새로운 기능을 참조하십시오 .

이 새로운 구현의 순서 유지 측면은 구현 세부 사항으로 간주되며 의존해서는 안됩니다 (향후 변경 될 수 있지만 언어 사양을 변경하기 전에 몇 가지 릴리스에 대해 언어 로이 새로운 dict 구현을 갖는 것이 바람직합니다 현재와 ​​미래의 모든 파이썬 구현에 대한 순서 유지 의미를 강제하기 위해; 이것은 또한 임의의 반복 순서가 여전히 유효한 이전 버전의 언어와의 하위 호환성을 유지하는 데 도움이됩니다 (예 : Python 3.5).

Python 3.7은이 구현 세부 사항을 언어 스펙으로 높이 므로 이제 dict해당 버전 이상과 호환되는 모든 Python 구현에서 순서 를 유지 해야합니다 . BDFL선언을 참조하십시오 .

collections.OrderedDict()클래스 는 표준 dict유형 외에 추가 기능을 제공하기 때문에 특정 경우에 클래스 를 계속 사용할 수 있습니다 . 이러한 인만큼 가역 (이는 확장 뷰 객체 ) 및 (비아 재정렬지지 move_to_end()방식 ).


답변

from collections import OrderedDict
OrderedDict((word, True) for word in words)

포함

OrderedDict([('He', True), ('will', True), ('be', True), ('the', True), ('winner', True)])

값이 True(또는 다른 불변의 객체 인 경우) 다음을 사용할 수도 있습니다.

OrderedDict.fromkeys(words, True)


답변

이론적 인 부분을 설명하는 대신 간단한 예를 들겠습니다.

>>> from collections import OrderedDict
>>> my_dictionary=OrderedDict()
>>> my_dictionary['foo']=3
>>> my_dictionary['aol']=1
>>> my_dictionary
OrderedDict([('foo', 3), ('aol', 1)])
>>> dict(my_dictionary)
{'foo': 3, 'aol': 1}


답변

이 답변은 python3.7 이전의 Python 버전에 적용됩니다. CPython 3.6은 대부분의 상황에서 구현 세부 사항으로 삽입 순서를 유지합니다. Python3.7부터는 구현시 반드시 삽입 순서를 준수해야한다고 선언되었습니다.


파이썬 사전은 순서가 없습니다. 정렬 된 사전을 원하면 collections.OrderedDict를 시도하십시오 .

OrderedDict는 python 2.7의 표준 라이브러리에 도입되었습니다. 이전 버전의 python을 사용하는 경우 ActiveState 에서 주문 된 사전에 대한 레시피를 찾을 수 있습니다 .


답변

사전은 검색을 효율적으로하는 순서를 사용하며이를 변경할 수 없습니다.

객체 목록 (간단한 경우에는 2 요소 튜플 또는 클래스)을 사용하고 항목을 끝에 추가 할 수 있습니다. 그런 다음 선형 검색을 사용하여 항목을 찾을 수 있습니다.

또는 순서를 유지하기 위해 작성된 다른 데이터 구조를 작성하거나 사용할 수 있습니다.


답변

OrderedDict를 작동시키는 방법을 알아 내려고 노력 하면서이 게시물을 보았습니다. PyDev for Eclipse는 OrderedDict를 전혀 찾을 수 없었으므로 주문을 원하는대로 사전 키 값의 튜플을 작성하기로 결정했습니다. 내 목록을 출력해야 할 때 튜플의 값을 반복하고 튜플에서 반복 된 ‘키’를 사전에 꽂아 필요한 순서대로 값을 검색했습니다.

예:

test_dict = dict( val1 = "hi", val2 = "bye", val3 = "huh?", val4 = "what....")
test_tuple = ( 'val1', 'val2', 'val3', 'val4')
for key in test_tuple: print(test_dict[key])

그것은 귀찮은 일이지만 시간이 지났으며 내가 생각해 낸 해결 방법입니다.

참고 : 목록 목록은 순서가 지정되고 색인이 작성되며 사전과 다른 구조이므로 다른 사람이 제안한 목록 접근 방식은 실제로 이해가되지 않습니다.


답변

사전으로 원하는 것을 실제로 할 수는 없습니다. 사전이 이미 d = {'ac':33, 'gw':20, 'ap':102, 'za':321, 'bs':10}작성되었습니다. 이미 만들어진 순서대로 유지할 방법이 없다는 것을 알았습니다. 내가 한 것은 객체 대신 json 파일을 만드는 것입니다.

{"ac":33,"gw":20,"ap":102,"za":321,"bs":10}

나는 사용했다 :

r = json.load(open('file.json'), object_pairs_hook=OrderedDict)

그런 다음 사용 :

print json.dumps(r)

확인합니다.