Programing

Python 3.6 이상에서 사전이 주문됩니까?

lottogame 2020. 2. 27. 22:06
반응형

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_indicesdk_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것은 ints 를 저장하기위한 희소 배열보다 훨씬 더 많은 메모리를 요구 합니다.

관심이 있다면이 기능에 관한 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



반응형