개발/Python

[파이썬] 딕셔너리에서 선언된 것과 같은 순서로 유지하는 방법?

MinorMan 2023. 1. 20. 13:06
반응형

<질문>

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

따라서 사전이 있는 경우:

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

내가 그것을 보거나 반복하면 그 순서가 아닙니다. 키/값을 선언한 명시적 순서를 Python이 유지하도록 할 방법이 있습니까?


<답변1>

파이썬 3.6부터 표준dicttype은 기본적으로 삽입 순서를 유지합니다.

정의

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

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

이는 스파스 해시 테이블에 대한 정수가 포함된 간단한 배열을 사용하여 달성되었습니다. 여기서 이러한 정수는 키-값 쌍(및 계산된 해시)을 저장하는 다른 배열로 인덱싱됩니다. 후자의 배열은 항목을 삽입 순서로 저장하며 전체 조합은 실제로 Python 3.5 및 이전 버전에서 사용된 구현보다 적은 메모리를 사용합니다. 참조original idea post by Raymond Hettinger자세한 내용은

3.6에서 이것은 여전히 구현 세부 사항으로 간주되었습니다. 참조What's New in Python 3.6 documentation:

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

Python 3.7은 이 구현 세부 사항을언어 사양, 따라서 이제 필수입니다.dict해당 버전 이상과 호환되는 모든 Python 구현에서 순서를 유지합니다. 참조pronouncement by the BDFL. Python 3.8부터는 사전도 지원합니다.iteration in reverse.

여전히collections.OrderedDict() class경우에 따라 표준 외에 몇 가지 추가 기능을 제공하기 때문입니다.dict유형. 와 같은reversible(이것은view objects) 및 재정렬 지원(move_to_end() method).


<답변2>

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)

<답변3>

이론적인 부분을 설명하기보다 간단한 예를 들어보겠습니다.

>>> 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}

<답변4>

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

파이썬 사전은 순서가 없습니다. 주문한 사전을 원하시면 해보세요collections.OrderedDict.

OrderedDict는 Python 2.7의 표준 라이브러리에 도입되었습니다. 이전 버전의 Python이 있는 경우 다음에서 순서가 지정된 사전에 대한 레시피를 찾을 수 있습니다.ActiveState.


<답변5>

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

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

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


<답변6>

OrderedDict를 작동시키는 방법을 알아내려고 노력하는 동안 이 게시물을 보았습니다. Eclipse용 PyDev는 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])

조금 번거롭지만 시간이 촉박하고 제가 생각해 낸 해결 방법입니다.

참고: 다른 사람이 제안한 목록 접근 방식은 목록이 정렬되고 인덱싱되기 때문에(또한 사전과 다른 구조이기 때문에) 나에게 실제로 의미가 없습니다.


<답변7>

사전으로는 원하는 것을 실제로 할 수 없습니다. 당신은 이미 사전을 가지고 있습니다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)

확인합니다.


<답변8>

from collections import OrderedDict
list1 = ['k1', 'k2']
list2 = ['v1', 'v2']
new_ordered_dict = OrderedDict(zip(list1, list2))
print new_ordered_dict
# OrderedDict([('k1', 'v1'), ('k2', 'v2')])

<답변9>

또 다른 대안은 Pandas를 사용하는 것입니다.dataframe딕셔너리와 같은 구조에서 항목의 순서와 색인 위치를 보장하기 때문입니다.


<답변10>

Django 프로젝트를 개발할 때 비슷한 문제가 있었습니다. 이전 버전의 Python을 실행 중이었기 때문에 OrderedDict를 사용할 수 없었기 때문에 해결책은 Django의 SortedDict 클래스를 사용하는 것이었습니다.

https://code.djangoproject.com/wiki/SortedDict

예를 들어

from django.utils.datastructures import SortedDict
d2 = SortedDict()
d2['b'] = 1
d2['a'] = 2
d2['c'] = 3

참고: 이 답변은 원래 2011년에 작성되었습니다. Python 버전 2.7 이상에 대한 액세스 권한이 있는 경우 현재 표준에 대한 액세스 권한이 있어야 합니다.collections.OrderedDict, 이 스레드의 다른 사람들이 많은 예를 제공했습니다.


<답변11>

일반적으로 사전처럼 동작하는 클래스를 설계할 수 있으며 주로 메서드를 구현합니다.__contains__,__getitem__,__delitem__,__setitem__그리고 좀 더. 해당 클래스는 예를 들어 정렬된 반복자를 키에 대해 권한을 부여하는 등 원하는 모든 동작을 가질 수 있습니다.


<답변12>

특정 순서로 사전을 갖고 싶다면 목록 목록을 만들 수도 있습니다. 여기서 첫 번째 항목은 키이고 두 번째 항목은 값이며 다음 예와 같습니다.

>>> list =[[1,2],[2,3]]
>>> for i in list:
...     print i[0]
...     print i[1]

1
2
2
3

<답변13>

내가 사전에서 했던 것과 같은 일을 할 수 있습니다.

목록과 빈 사전을 만듭니다.

dictionary_items = {}
fields = [['Name', 'Himanshu Kanojiya'], ['email id', 'hima@gmail.com']]
l = fields[0][0]
m = fields[0][1]
n = fields[1][0]
q = fields[1][1]
dictionary_items[l] = m
dictionary_items[n] = q
print dictionary_items
반응형