2012-12-21 2 views
7

은 내가 hash(a)hash(b)가 같은 값을 반환하기 때문에 d는 하나의 쌍을 유지하는 이유라고 처음에는 생각 파이썬 사전 수수께끼

>>> class S(str): pass 
... 
>>> a = 'hello' 
>>> b = S('hello') 
>>> d = {a:a, b:b} 
>>> d 
{'hello': 'hello'} 
>>> type(d[a]) 
<class '__main__.S'> 
>>> type(d[b]) 
<class '__main__.S'> 

에 입력, 그래서 시도 :

>>> class A(object): 
...  def __hash__(self): 
...    return 0 
... 
>>> class B(object): 
...  def __hash__(self): 
...    return 0 
... 
>>> d = {A():A(),B():B()} 
>>> d 
{<__main__.A object at 0x101808b90>: <__main__.A object at 0x101808b10>, <__main__.B object at 0x101808d10>: <__main__.B object at 0x101808cd0>} 

이제 혼란스러워합니다. 첫 번째 코드 목록을 보면 d은 한 쌍만 유지되었지만 두 번째 목록에서는 동일한 해시를 가지고 있더라도 d 두 키가 모두 유지 되었습니까?

답변

8

원본 예제의 두 개체는 해시가 같기 때문에가 아니라 동일한 것으로 비교되므로 병합되었습니다. Dict 키는 해시가 아닌 항등식과 관련하여 고유합니다. 파이썬은 평등을 비교하는 두 객체가 같은 해시를 가져야한다는 것을 요구합니다 (반드시 반대는 아닙니다).

첫 번째 예에서는 두 개체가 모두 같음 (str 동일 동작). 두 개체가 동일하게 비교되므로 하나의 개체로 축소됩니다. 두 번째 예에서 그들은 동일하지 않습니다. 기본적으로 사용자 정의 클래스는 동일성을 위해 ID를 사용합니다. 즉, 각 객체는 자신과 동등한 비교를합니다. 그래서 당신의 두 대상은 같지 않습니다. 동일한 해시를 갖는 것보다 중요하지 않습니다.

0

첫 번째 및 두 번째 개체의 키가 다릅니다. 그들이 객체이기 때문에 열쇠는 객체가 문자열이 아닌 읽을 수있는 등가물입니다.

4

해시는 사전의 고유 키를 결정하지 않습니다. 어떤면에서 해시 함수는 사전이 내부적으로 항목을 저장하는 방법을 결정한다는 점에서 "구현 세부 사항"입니다. a == b는 hash (a) == hash (b)를 의미하지만, 그 반대는 일반적으로 보류하지 않습니다. 두 개의 키는 == 연산자를 적용 할 때 서로 동일해야 사전에있는 동등한 키로 취급됩니다.