파이썬 사전은 해시 테이블의 예입니까?


187

파이썬의 기본 데이터 구조 중 하나는 사전이며, 어떤 유형의 "값"을 찾기 위해 "키"를 기록 할 수 있습니다. 내부적으로 해시 테이블로 구현 되었습니까? 그렇지 않다면 무엇입니까?


2
기술적 세부 사항에 관심이 있다면 Beautiful Code의 한 기사 가 Python dict구현 의 내부 내용을 다룹니다 .
Torsten Marek

그것은 Beautiful Code에서 제가 가장 좋아하는 장 중 하나였습니다.
DGentry

4
다음은 Brandon Craig Rhodes의 python 사전 작동 방식에 대한 이야기입니다 ( youtube.com/watch?v=C4Kc8xzcA68) .
chandola

메모리와 CPython의 구현을 설명하는 한동안 dict을 나타내는 다이어그램을 찾았습니다. 책을 참조 해 주셔서 감사합니다!
Chen A.

답변:


239

예, 해시 매핑 또는 해시 테이블입니다. , 팀 피터스 (Tim Peters)에 의해 기록 된대로, 파이썬의 DICT 구현에 대한 설명을 읽을 수 있습니다 여기에 .

그렇기 때문에리스트처럼 '해시 불가능'을 dict 키로 사용할 수없는 이유는 다음과 같습니다.

>>> a = {}
>>> b = ['some', 'list']
>>> hash(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable
>>> a[b] = 'some'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable

당신은 할 수 해시 테이블에 대한 자세한 내용 이나 이 파이썬으로 구현되었는지를 확인 하고 이 방법이 있음을 구현하는 이유 .


1
팀 피터스 연결선 이음새가 끊어졌습니다. 깨끗한 연결선이 있습니까?
매트 알콕

1
@ MatAlcock : 링크를 업데이트했습니다. 때때로 (보통 누군가가 이메일 주소를 제거하기를 원하기 때문에) 파이썬 목록 아카이브가 재구성되고 이메일 ID가 변경되어 링크가 끊어집니다. pydotorg 관리자는 일반적으로 요즘 그것을 피하려고합니다.
Martijn Pieters

그러나를 사용 .keys()하면 키 목록을 검색 할 수 있습니다. 실제 해시 테이블은 키를 저장하지 않고 공간을 절약하기 위해 해시합니다.
noɥʇʎԀʎzɐɹƆ

파이썬 dict 구현에 대한 자세한 설명은 다음과 같습니다. laurentluce.com/posts/python-dictionary-implementation
Daniel Goldfarb

32

hash ()의 테이블 조회보다 파이썬 사전에 더 많은 것이 있어야합니다. 무차별 실험 으로이 해시 충돌을 발견했습니다 .

>>> hash(1.1)
2040142438
>>> hash(4504.1)
2040142438

그러나 그것은 사전을 깨뜨리지 않습니다.

>>> d = { 1.1: 'a', 4504.1: 'b' }
>>> d[1.1]
'a'
>>> d[4504.1]
'b'

위생 점검:

>>> for k,v in d.items(): print(hash(k))
2040142438
2040142438

아마도 사전 키 사이의 충돌을 피하는 hash () 이외의 다른 조회 수준이있을 수 있습니다. 또는 dict ()는 다른 해시를 사용합니다.

(이것은 파이썬 2.7.10에서입니다. 파이썬 3.4.3과 3.5.0에서 같은 이야기가 충돌 hash(1.1) == hash(214748749.8)합니다.)


14
따라서 충돌은 피할 수 없습니다. 세트 S는 무한히 많은 수의 항목을 포함 할 수 있으며 컴퓨터가 저장할 수있는 수로 해시하기를 원합니다. 사용 가능한 모든 해시 테이블 구현은 충돌을 해결하며 가장 빈번한 두 가지 방법은 a) 공개 주소 지정과 b) 체인입니다. 완벽한 해시를 사용하지 않는다고해서 해시 테이블이 아니라는 의미는 아닙니다.
TurnipEntropy 2016

1
가능한 가능한 해시 값과 유한 해시 코드가 있기 때문에 충돌이 일반적으로 발생합니다. 해시 테이블조차도 어떻게 든 충돌을 처리해야합니다.
Yanfeng Liu

3
@ YanfengLiu 나는 이것이 TurnipEntropy와 정확히 같은 점이라고 생각합니다.
밥 스타

1
파이썬 3.7에서는 실제로 2E20 빼기 1 가능한 해시 값이있는 것처럼 보입니다. 시도 1. (+) 1E20 마이너스로 -1E20 마이너스 1 일부터 hash('I wandered lonely as a cloud, that drifts on high o\'er vales and hills, when all at once, I saw a crowd, a host of golden daffodils.')이를 19 자리의 소수를 제공합니다 - -4037225020714749784당신이있는 거 괴짜의 충분한 경우 치료에. 자신의 단어, 아이들로 계속 해시는 여전히 19 자리 숫자입니다. 파이썬에서 해시 할 수있는 문자열 길이에 제한이 있다고 가정하지만 가능한 값보다 더 많은 가능한 문자열을 말하는 것이 안전합니다. 그런데 hash(False)= 0입니다.
Will Croxford


7

nosklo의 설명을 확장하려면 :

a = {}
b = ['some', 'list']
a[b] = 'some' # this won't work
a[tuple(b)] = 'some' # this will, same as a['some', 'list']
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.