Python 3.6 이상에서 사전이 주문됩니까?
사전은 이전 화신과 달리 Python 3.6 (최소한 CPython 구현)에서 주문됩니다. 이것은 실질적인 변화처럼 보이지만 문서 의 짧은 단락 일뿐 입니다. 언어 기능이 아닌 CPython 구현 세부 사항으로 설명되지만 앞으로 이것이 표준이 될 수 있음을 암시합니다.
요소 사전을 유지하면서 새로운 사전 구현이 이전 사전보다 어떻게 더 잘 수행됩니까?
다음은 설명서의 텍스트입니다.
dict()
이제 PyPy가 개척 한 "소형"표현을 사용합니다 . 새로운 dict ()의 메모리 사용량은 Python 3.5에 비해 20 %에서 25 % 사이입니다. PEP 468 (함수에서 ** kwargs의 순서 유지)이 구현됩니다. 이 새로운 구현의 순서 유지 측면은 구현 세부 사항으로 간주되며 의존해서는 안됩니다 (향후 변경 될 수 있지만 언어 사양을 변경하기 전에 몇 가지 릴리스에 대해 언어 로이 새로운 dict 구현을 갖는 것이 바람직합니다 현재와 미래의 모든 파이썬 구현에 대한 순서 유지 의미론을 강제하기 위해; 이것은 또한 임의의 반복 순서가 여전히 유효한 이전 버전의 언어와의 하위 호환성을 유지하는 데 도움이됩니다 (예 : Python 3.5). (INADA Naoki가 제공 한문제 27350 . Raymond Hettinger가 처음 제안한 아이디어 .)
2017 년 12 월 업데이트 : Python 3.7에 대한 게재 dict
신청서 유지 보장
Python 3.6 이상에서 사전이 주문됩니까?
그것들은 삽입 순서가되어있다 [1] . Python 3.6부터 CPython Python 구현에서 사전 은 삽입 된 항목의 순서를 기억합니다 . 이것은 Python 3.6에서 구현 세부 사항으로 간주됩니다 . 다른 파이썬 구현 OrderedDict
에서 보장 되는 삽입 순서 (및 기타 정렬 된 동작 [1] ) 를 원할 경우 사용해야 합니다 .
Python 3.7부터는 더 이상 구현 세부 사항이 아니며 언어 기능이됩니다. GvR의 python-dev 메시지에서 :
그렇게 만들어. "사전 삽입 순서 유지"는 판결입니다. 감사!
이것은 단순히 당신이 그것에 의존 할 수 있다는 것을 의미 합니다 . 파이썬의 다른 구현은 파이썬 3.7의 적합한 구현이 되려면 삽입 순서 사전을 제공해야합니다.
어떻게 파이썬 않는
3.6
사전 구현은 더 잘 수행 [2] 이전보다가 그대로 유지하면서 요소 순서를?
본질적으로 두 개의 배열 을 유지함으로써 .
첫 번째 배열 인 에는 사전에 대한
dk_entries
항목 ( 유형PyDictKeyEntry
)을 삽입 된 순서대로 보유합니다 . 보존 순서는 새 항목이 항상 끝에 삽입되는 추가 전용 배열 (삽입 순서)로 이루어집니다.두 번째
dk_indices
는dk_entries
배열 의 인덱스 (즉,에서 해당 항목의 위치를 나타내는 값dk_entries
)를 보유합니다. 이 배열은 해시 테이블 역할을합니다. 키가 해시되면 키가 저장된 인덱스 중 하나로 연결되고dk_indices
해당 항목은 색인화하여 가져옵니다dk_entries
. 인덱스 만이 유지되므로, 이러한 배열의 형태가 사전의 전체 크기 (레인 징의 타입에 따라int8_t
(1
바이트)로int32_t
/int64_t
(4
/8
바이트)에32
/64
비트 빌드)
이전 구현에서는 유형 PyDictKeyEntry
과 크기 의 희소 배열을 dk_size
할당해야했습니다. 불행히도, 성능상의 이유로 어레이가 2/3 * dk_size
가득 차는 것을 허용하지 않았기 때문에 빈 공간이 많이 생겼습니다 . (그리고 빈 공간에는 여전히 크기 가 있습니다!).PyDictKeyEntry
단지 때문에 지금 그렇지 않다 필요한 항목의 입력은 희소 배열 (삽입 된 것)에 저장된다 intX_t
( X
딕셔너리 크기에 따라) 2/3 * dk_size
의 전체 유지된다. 빈 공간이 유형에서 PyDictKeyEntry
로 변경되었습니다 intX_t
.
따라서, 희소 한 유형의 배열을 생성하는 PyDictKeyEntry
것은 int
s 를 저장하기위한 희소 배열보다 훨씬 더 많은 메모리를 요구 합니다.
관심이 있다면이 기능에 관한 Python-Dev 의 전체 대화 를 볼 수 있습니다 .
Raymond Hettinger의 원래 제안 에서 아이디어의 요점을 포착하는 사용 된 데이터 구조의 시각화를 볼 수 있습니다.
예를 들어, 사전은 다음과 같습니다.
d = {'timmy': 'red', 'barry': 'green', 'guido': 'blue'}
현재 다음과 같이 저장됩니다 :
entries = [['--', '--', '--'], [-8522787127447073495, 'barry', 'green'], ['--', '--', '--'], ['--', '--', '--'], ['--', '--', '--'], [-9092791511155847987, 'timmy', 'red'], ['--', '--', '--'], [-6480567542315338377, 'guido', 'blue']]
대신, 데이터는 다음과 같이 구성되어야합니다.
indices = [None, 1, None, None, None, 0, None, 2] entries = [[-9092791511155847987, 'timmy', 'red'], [-8522787127447073495, 'barry', 'green'], [-6480567542315338377, 'guido', 'blue']]
시각적으로 볼 수 있듯이 원래 제안에서 충돌을 줄이고 조회 속도를 높이기 위해 많은 공간이 기본적으로 비어 있습니다. 새로운 접근 방식을 사용하면 인덱스에서 실제 필요한 위치에 스 퍼니스를 이동하여 필요한 메모리를 줄일 수 있습니다.
[1] : OrderedDict가 있으면 "ordered"는 dict
객체 가 제공하지 않는 추가 동작을 나타 내기 때문에 "inserted ordered" 가 아니라 "ordered"라고 말합니다 . OrderedDict는 가역적이며 순서에 민감한 방법을 제공하며 주로 순서에 민감한 평등 테스트 ( ==
, !=
)를 제공합니다. dict
현재 이러한 행동 / 방법을 제공하지 않습니다.
[2] : 새로운 딕셔너리 구현은보다 간결하게 디자인되어보다 나은 메모리 성능을 제공합니다 . 이것이 주요 이점입니다. 현명하게도, 그 차이는 그다지 급격하지는 않습니다. 새로운 dict이 약간의 회귀 ( 예 : 키 조회)를 유발할 수있는 반면, 다른 경우 (반복 및 크기 조정이 떠오를 때)에는 성능 향상이 있어야합니다.
전반적으로, 특히 실제 상황에서 사전의 성능은 도입 된 소형화로 인해 향상됩니다.
아래는 첫 번째 원래 질문에 대한 답변입니다.
나는 사용해야
dict
또는OrderedDict
파이썬 3.6?
나는 문서 의이 문장이 실제로 귀하의 질문에 대답하기에 충분하다고 생각합니다
이 새로운 구현의 순서 유지 측면은 구현 세부 사항으로 간주되며 이에 의존해서는 안됩니다.
dict
는 명시 적으로 정렬 된 컬렉션을 의미하는 것이 아니므로 일관성을 유지하고 새 구현의 부작용에 의존하지 않으려면를 사용해야합니다 OrderedDict
.
미래의 코드 증명 :)
여기에 대한 토론이 있습니다 .
편집 : 파이썬 3.7는 기능으로이 유지됩니다 참조
업데이트 : Guido van Rossum 은 메일 링리스트dict
에서 모든 Python 구현에서 Python 3.7부터 삽입 순서를 유지해야 한다고 발표했습니다 .
위의 토론에 추가하고 싶었지만 언급 할만한 평판이 없습니다.
Python 3.8은 아직 출시되지 않았지만 reversed()
사전에 대한 기능 도 포함합니다 (와 다른 차이점 제거) OrderedDict
.
딕 트뷰와 dictviews는 이제 reversed ()를 사용하여 역 삽입 순서로 반복 가능합니다. (pyo 33462의 Rémi Lapeyre 제공) Python 3.8의 새로운 기능보기
평등 연산자 또는 다른 기능에 대한 언급이 OrderedDict
없으므로 완전히 동일하지 않습니다.
참고 URL : https://stackoverflow.com/questions/39980323/are-dictionaries-order-in-python-3-6
'Programing' 카테고리의 다른 글
iPhone은 첫 페이지에서만 탐색 모음을 숨 깁니다. (0) | 2020.02.27 |
---|---|
서포트 벡터 머신에 비해 인공 신경망의 장점은 무엇입니까? (0) | 2020.02.27 |
JavaScript에서 문자열을 비교하는 가장 좋은 방법은 무엇입니까? (0) | 2020.02.27 |
Apple 개발자 프로그램이나 탈옥이없는 기기에서 iOS 앱 테스트 (0) | 2020.02.27 |
PHP 문자열을 JavaScript 변수에 전달하고 줄 바꿈을 피하십시오. (0) | 2020.02.27 |