2017-11-30 1 views
3

파이썬에서 사전은 키를 해싱하고 배열에 키 - 값 쌍에 대한 포인터를 저장하여 사전이 구현된다는 것을 알고 있습니다. 인덱스는 해시에 의해 결정됩니다.파이썬 사전은 포인터의 해시 맵입니다 ... 무엇?

그러나 키 - 값 쌍 자체는 어떻게 저장됩니까? 그것들은 함께 저장되어 있습니까 (즉, 연속적으로 메모리에 저장되어 있습니까?)? 하나의 키와 하나의 값을 가리키는 터플이나 포인터 배열로 저장되어 있습니까? 아니면 완전히 다른 것입니까?

인터넷 검색은 해싱 및 공개 주소 지정 등에 대한 설명이 많이 나오지만이 질문은 다루지 않았습니다.

+0

이것은 구현에 따라 다르며 하나 이상의 Python 구현이 있음에 유의하십시오. 나는 CPython, PyPy, IronPython, Jython을 생각할 수있다. 나도 몰라,하지만 IronPython과 Jython이 .Net/Java Map을 사용할 것으로 기대한다. 사전을 구현하는 것. –

+2

레이몬드 헤 팅거 (Raymond Hetttinger)의 파이썬 사전의 다양한 버전에 대한 훌륭한 토론이 있습니다 : https://www.youtube.com/watch?v=npw4s1QTmPg – chthonicdaemon

답변

1

대략 함수가 있습니다. F이라고 부르며, 값 배열에 인덱스 F(h)을 계산합니다. 따라서 값은 배열로 저장되며 이들은 F(h)으로 조회됩니다. "대략 말하기"하는 이유는 해시가 서로 다른 객체에 대해 다르게 계산된다는 것입니다. 예를 들어 포인터의 경우 p>>3; 문자열의 경우 해시는 문자열의 모든 바이트를 요약 한 것입니다.

C 코드를 보려면 lookdict_index을 검색하거나 CPython의 소스 코드에서 dictobject.c 파일을 살펴보십시오. C 코드를 읽는 데 익숙하다면 꽤 읽기 쉽습니다.

편집 1 :

/* 
The DictObject can be in one of two forms. 

Either: 
    A combined table: 
    ma_values == NULL, dk_refcnt == 1. 
    Values are stored in the me_value field of the PyDictKeysObject. 
Or: 
    A split table: 
    ma_values != NULL, dk_refcnt >= 1 
    Values are stored in the ma_values array. 
    Only string (unicode) keys are allowed. 
    All dicts sharing same key must have same insertion order. 
.... 
*/ 

값이 하나 저장됩니다

/* If ma_values is NULL, the table is "combined": keys and values 
    are stored in ma_keys. 

    If ma_values is not NULL, the table is splitted: 
    keys are stored in ma_keys and values are stored in ma_values */ 

그리고 dictobject :에서 설명 : 파이썬에서 주석에서 는의가/dictobject.h 포함 3.6.1 「열쇠 오브젝트」의 배열을 따르는 캐릭터 라인의 배열입니다. 또는 각 값의 포인터는 me_valuePyDictKeyEntry에 저장됩니다. 키는 me_key 필드에 PyDictKeyEntry으로 저장됩니다. 키 배열은 실제로 PyDictKeyEntry 구조체의 배열입니다. 파이썬의 소스/dictobject.h 객체/DICT-common.h, 객체/dictobject.c 및 포함 :

typedef struct { 
     /* Cached hash code of me_key. */ 
     Py_hash_t me_hash; 
     PyObject *me_key; 
     PyObject *me_value; /*This field is only meaningful for combined tables*/ 
    } PyDictKeyEntry; 

관련 보는 파일 : 그냥 참고로

, PyDictKeyEntry는 다음과 같이 정의된다 암호.

Objects/dictobject.c는 전체 구성표와 배경 지식을 설명하는 파일의 시작 부분에 주석으로 광범위한 내용을 기록합니다.

+0

예, 해쉬 함수에 대해 알고 있습니다. 파이썬은 배열에서 키 - 값 쌍에 포인터를 집어 넣는 부분을 알고 있습니다. 그러나 키 - 값 쌍 자체는 어떻게 저장됩니까? (내 질문은 정말 키 - 값 _pair_ 때문입니다. 세트의 경우 포인터를 항목을 가리키고 가정합니다.하지만 키 및 값이 있기 때문에, 나는 그들이 어떻게 저장 궁금해.) ... 또는 값에 대한 포인터를 저장하는 _second_ 배열이 있고 원래 배열에 키에 대한 포인터가 저장되어 있다고 말하고 있습니까? 일치하는 인덱스를 통해 일치가 생성됩니까? –

+0

@Katie, "Edit 1"다음에 자세한 내용을 추가했습니다. 아직도 불분명하거나 TL이라면, 제발, 알려주세요. –

+0

고마워요, @ 드미트리, 내가 그것을 조사하겠습니다! –

관련 문제