[python] 파이썬에서 “해시 가능”은 무엇을 의미합니까?

인터넷 검색을 시도했지만 해시 가능의 의미를 찾을 수 없습니다.

그들이 물건이라고 말 hashable하거나 hashable objects무엇을 의미합니까?



답변

로부터 파이썬 용어 :

객체는 수명 동안 변경되지 않는 ( __hash__()메소드 필요 ) 해시 값이 있고 다른 객체 ( __eq__()또는 __cmp__()메소드 필요)와 비교할 수있는 경우 해시 가능합니다 . 동일하게 비교하는 해시 가능 객체는 동일한 해시 값을 가져야합니다.

해시 기능을 사용하면 객체가 사전 키 및 집합 멤버로 사용할 수 있습니다. 이러한 데이터 구조는 해시 값을 내부적으로 사용하기 때문입니다.

파이썬의 변경 불가능한 내장 객체는 모두 해시 가능하지만 변경 가능한 컨테이너 (예 : 목록 또는 사전)는 없습니다. 사용자 정의 클래스의 인스턴스 인 객체는 기본적으로 해시 가능합니다. 그들은 모두 불평등을 비교하며 해시 값은 그들의 것 id()입니다.


답변

여기에있는 모든 대답에는 파이썬에서 해시 가능한 객체에 대한 효과적인 설명이 있지만 해싱이라는 용어를 먼저 이해해야한다고 생각합니다.

해싱 은 많은 양의 데이터를 빠르게 저장하고 액세스하는 고성능 의사 랜덤 액세스 데이터 구조를 만드는 데 사용되는 컴퓨터 과학의 개념입니다.

예를 들어 전화 번호가 10,000 개이고 배열 (연속적인 메모리 위치에 데이터를 저장하고 임의 액세스를 제공하는 순차적 데이터 구조)에 저장하려는 경우 필요한 양의 연속성이 없을 수 있습니다. 메모리 위치.

따라서 대신 크기가 100 인 배열을 사용하고 해시 함수를 사용하여 값 집합을 동일한 인덱스에 매핑하면 이러한 값을 연결된 목록에 저장할 수 있습니다. 이것은 어레이와 비슷한 성능을 제공합니다.

이제 해시 함수는 숫자를 배열의 크기로 나누고 나머지를 인덱스로 사용하는 것처럼 간단 할 수 있습니다.

자세한 내용은 https://en.wikipedia.org/wiki/Hash_function참조하십시오.

또 다른 좋은 참고 자료는 다음과 같습니다. http://interactivepython.org/runestone/static/pythonds/SortSearch/Hashing.html


답변

변경할 수없는 (변경 가능한 수단, 변경 가능성이있는) 항목은 해시 할 수 있습니다. 예를 들어 클래스에 클래스가 있으면 해시 함수를 찾아야합니다. 방법을 dir(tuple)찾고 __hash__여기에 몇 가지 예가 있습니다.

#x = hash(set([1,2])) #set unhashable
x = hash(frozenset([1,2])) #hashable
#x = hash(([1,2], [2,3])) #tuple of mutable objects, unhashable
x = hash((1,2,3)) #tuple of immutable objects, hashable
#x = hash()
#x = hash({1,2}) #list of mutable objects, unhashable
#x = hash([1,2,3]) #list of immutable objects, unhashable

불변 타입의리스트 :

int, float, decimal, complex, bool, string, tuple, range, frozenset, bytes

변경 가능한 유형 목록 :

list, dict, set, bytearray, user-defined classes


답변

파이썬 용어에 따르면 필자는 해시 가능한 객체의 인스턴스를 만들 때 인스턴스의 멤버 또는 값에 따라 변경 불가능한 값도 계산됩니다. 예를 들어,이 값을 아래와 같이 dict의 키로 사용할 수 있습니다.

>>> tuple_a = (1,2,3)
>>> tuple_a.__hash__()
2528502973977326415
>>> tuple_b = (2,3,4)
>>> tuple_b.__hash__()
3789705017596477050
>>> tuple_c = (1,2,3)
>>> tuple_c.__hash__()
2528502973977326415
>>> id(a) == id(c)  # a and c same object?
False
>>> a.__hash__() == c.__hash__()  # a and c same value?
True
>>> dict_a = {}
>>> dict_a[tuple_a] = 'hiahia'
>>> dict_a[tuple_c]
'hiahia'

tuple_a와 tuple_c의 해시 값은 동일한 멤버를 갖기 때문에 동일하다는 것을 알 수 있습니다. dict_a의 키로 tuple_a를 사용하면 dict_a [tuple_c]의 값이 동일하다는 것을 알 수 있습니다. 즉, dict의 키로 사용될 때 해시 값이 같기 때문에 동일한 값을 반환합니다. 똑같다. 해시 가능 하지 않은 객체의 경우 해시 메소드 는 없음으로 정의됩니다.

>>> type(dict.__hash__)
<class 'NoneType'>

이 해시 값은 동적으로가 아닌 인스턴스 초기화시 계산되므로 불변의 객체 만 해시 가능합니다. 도움이 되었기를 바랍니다.


답변

파이썬에서 해시 가능한 객체를 이해하는 실제 예를 들어 보겠습니다. 이 예제에서는 2 개의 튜플을 사용하고 있습니다. 튜플의 각 값에는 고유 한 해시 값이 있으며 수명 기간 동안 절대 변하지 않습니다. 따라서이 값을 기반으로 두 튜플 간의 비교가 수행됩니다. Id ()를 사용하여 튜플 요소의 해시 값을 얻을 수 있습니다.

2 개의 튜플 비교두 튜플의 동등성


답변

파이썬에서는 객체가 인덱스를 반환하기 위해 세트의 멤버가 될 수 있음을 의미합니다. 즉, 고유 한 ID / ID가 있습니다.

예를 들어, 파이썬 3.3에서 :

데이터 구조리스트는 해시 가능하지 않지만 데이터 구조 터플은 해시 가능합니다.


답변

해시 가능 = 해시 가능

좋아, 해싱이란 무엇인가? 해싱 함수는 “Python”과 같은 문자열과 같은 개체를 가져 와서 고정 크기 코드를 반환하는 함수입니다. 간단히하기 위해 반환 값이 정수라고 가정합니다.

Python 3에서 hash ( ‘Python’)을 실행하면 결과로 5952713340227947791이 표시됩니다. 다른 버전의 Python은 기본 해시 함수를 자유롭게 변경할 수 있으므로 다른 값을 얻을 수 있습니다. 중요한 것은 지금 여러 번 해시 ( ‘Python’)를 실행하더라도 항상 동일한 버전의 Python으로 동일한 결과를 얻을 수 있다는 것입니다.

그러나 hash ( ‘Java’)는 1753925553814008565를 반환합니다. 따라서 해싱하는 객체가 변경되면 결과도 변경됩니다. 반면 해싱중인 객체가 변경되지 않으면 결과는 동일하게 유지됩니다.

이것이 왜 중요한가?

예를 들어, 파이썬 사전은 키를 변경할 수 없어야합니다. 즉, 키는 변경되지 않는 객체 여야합니다. 문자열은 다른 기본 유형 (int, float, bool)과 마찬가지로 Python에서 변경할 수 없습니다. 튜플 및 고정 세트도 변경할 수 없습니다. 반면, 목록은 변경할 수 없기 때문에 변경할 수 없습니다 (즉, 변경할 수 있음). 마찬가지로 dicts도 변경할 수 있습니다.

따라서 무언가 해쉬 가능하다고 말할 때, 그것은 불변이라는 것을 의미합니다. 변경 가능한 유형을 hash () 함수에 전달하려고하면 실패합니다.

>>> hash('Python')
1687380313081734297
>>> hash('Java')
1753925553814008565
>>>
>>> hash([1, 2])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> hash({1, 2})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> hash({1 : 2})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>>
>>> hash(frozenset({1, 2}))
-1834016341293975159
>>> hash((1, 2))
3713081631934410656