Nice programing

해시는 파이썬에서 무엇을합니까?

nicepro 2020. 11. 23. 20:02
반응형

해시는 파이썬에서 무엇을합니까?


hash함수가 튜플에 적용되는 코드의 예를 보았습니다 . 결과적으로 음의 정수를 반환합니다. 이 기능이 무엇을하는지 궁금합니다. Google은 도움이되지 않습니다. 해시 계산 방법을 설명하는 페이지를 찾았지만이 함수가 필요한 이유를 설명하지 않습니다.


해시는 특정 값을 식별하는 고정 된 크기의 정수입니다 . 각 값에는 고유 한 해시가 있어야하므로 동일한 값에 대해 동일한 객체가 아니더라도 동일한 해시를 얻게됩니다.

>>> hash("Look at me!")
4343814758193556824
>>> f = "Look at me!"
>>> hash(f)
4343814758193556824

해시 값은 결과 값이 균등하게 분산되어 발생하는 해시 충돌 수를 줄이는 방식으로 생성되어야합니다. 해시 충돌은 서로 다른 두 값이 동일한 해시를 가질 때 발생합니다. 따라서 상대적으로 작은 변경으로 인해 종종 매우 다른 해시가 발생합니다.

>>> hash("Look at me!!")
6941904779894686356

이 숫자는 큰 값 모음에서 값을 빠르게 조회 할 수 있으므로 매우 유용합니다. 두 가지 사용 예는 Python setdict. 에서 list값이 목록에 있는지 확인하려면을 사용하여 if x in values:Python이 전체 목록을 살펴보고 목록의 x각 값 과 비교 해야합니다 values. 이것은 오랜 시간이 걸릴 수 있습니다 list. A의 set, 파이썬은 각 해시를 추적하고 입력 할 때 if x in values:, 파이썬의 해시 값을 얻을 것이다 x, 내부 구조에이를보고 만 비교 x와 동일한 해시를 가지고있는 값 x.

동일한 방법론이 사전 조회에 사용됩니다. 이에 조회 수 setdict조회에가있는 동안, 매우 빠른 list느립니다. 또한에는 해시 할 수없는 객체를 가질 수 list있지만에는 set또는 dict. 해시 할 수없는 개체의 일반적인 예는 변경 가능한 개체로, 값을 변경할 수 있습니다. 변경 가능한 객체가있는 경우 해시 할 수 없어야합니다. 해시가 수명에 따라 변경되어 객체가 사전에서 잘못된 해시 값으로 끝날 수 있기 때문에 많은 혼란을 야기 할 수 있기 때문입니다.

값의 해시는 한 번의 Python 실행에 대해서만 동일해야합니다. Python 3.3에서는 실제로 Python이 새로 실행될 때마다 변경됩니다.

$ /opt/python33/bin/python3
Python 3.3.2 (default, Jun 17 2013, 17:49:21) 
[GCC 4.6.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> hash("foo")
1849024199686380661
>>> 
$ /opt/python33/bin/python3
Python 3.3.2 (default, Jun 17 2013, 17:49:21) 
[GCC 4.6.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> hash("foo")
-7416743951976404299

이것은 특정 문자열이 가질 해시 값을 추측하기가 더 어렵습니다. 이는 웹 애플리케이션 등에 중요한 보안 기능입니다.

따라서 해시 값은 영구적으로 저장되지 않아야합니다. 해시 값을 영구적으로 사용해야하는 경우 파일 등의 확인 가능한 체크섬을 만드는 데 사용할 수있는 보다 "심각한"유형의 해시, 암호화 해시 함수를 살펴볼 수 있습니다.


TL; DR :

용어집을 참조하십시오 : hash()객체를 비교하는 지름길로 사용되며 다른 객체와 비교할 수있는 객체는 해시 가능한 것으로 간주됩니다. 그것이 우리가 hash(). 또한 액세스하는 데 사용 dict하고 set로 구현 요소 의 CPython에서 크기 조정 해시 테이블 .

기술적 고려 사항

  • 일반적으로 객체 비교 (여러 수준의 재귀가 포함될 수 있음)는 비용이 많이 듭니다.
  • 바람직하게는, hash()함수는 훨씬 저렴하다.
  • 두 개의 해시를 비교하는 것이 두 객체를 비교하는 것보다 쉽습니다. 바로 가기가 여기에 있습니다.

사전이 구현되는 방법대해 읽으면 해시 테이블을 사용합니다. 즉, 객체에서 키를 파생하는 것은의 사전에서 객체를 검색하는 초석이됩니다 O(1). 그러나 충돌 방지 기능은 해시 함수에 따라 크게 달라집니다 . 항목을 가져 오는 최악의 경우 사전에이 사실이다 O(n).

참고로 변경 가능한 객체는 일반적으로 해시 할 수 없습니다. hashable 속성은 객체를 키로 사용할 수 있음을 의미합니다. 해시 값이 키로 사용되고 동일한 객체의 내용이 변경되면 해시 함수는 무엇을 반환해야합니까? 동일한 키입니까 아니면 다른 키입니까? 그것은 따라 당신이 당신의 해시 함수를 정의하는 방법에.

예제로 배우기 :

이 클래스가 있다고 상상해보십시오.

>>> class Person(object):
...     def __init__(self, name, ssn, address):
...         self.name = name
...         self.ssn = ssn
...         self.address = address
...     def __hash__(self):
...         return hash(self.ssn)
...     def __eq__(self, other):
...         return self.ssn == other.ssn
... 

참고 : 이것은 모두 SSN이 개인에 대해 절대 변경되지 않는다는 가정을 기반으로합니다 (신뢰할 수있는 출처에서 실제로 그 사실을 어디에서 확인해야할지조차 모릅니다).

그리고 우리는 Bob이 있습니다.

>>> bob = Person('bob', '1111-222-333', None)

Bob은 이름을 변경하기 위해 판사를 만나러갑니다.

>>> jim = Person('jim bo', '1111-222-333', 'sf bay area')

이것이 우리가 알고있는 것입니다.

>>> bob == jim
True

그러나 이들은 같은 사람에 대한 두 개의 다른 레코드처럼 할당 된 다른 메모리를 가진 두 개의 다른 개체입니다.

>>> bob is jim
False

이제 hash ()가 편리한 부분이 있습니다.

>>> dmv_appointments = {}
>>> dmv_appointments[bob] = 'tomorrow'

뭔지 맞춰봐:

>>> dmv_appointments[jim] #?
'tomorrow'

From two different records you are able to access the same information. Now try this:

>>> dmv_appointments[hash(jim)]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 9, in __eq__
AttributeError: 'int' object has no attribute 'ssn'
>>> hash(jim) == hash(hash(jim))
True

What just happened? That's a collision. Because hash(jim) == hash(hash(jim)) which are both integers btw, we need to compare the input of __getitem__ with all items that collide. The builtin int does not have an ssn attribute so it trips.

>>> del Person.__eq__
>>> dmv_appointments[bob]
'tomorrow'
>>> dmv_appointments[jim]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: <__main__.Person object at 0x7f611bd37110>

In this last example, I show that even with a collision, the comparison is performed, the objects are no longer equal, which means it successfully raises a KeyError.


The Python docs for hash() state:

Hash values are integers. They are used to quickly compare dictionary keys during a dictionary lookup.

Python dictionaries are implemented as hash tables. So any time you use a dictionary, hash() is called on the keys that you pass in for assignment, or look-up.

Additionally, the docs for the dict type state:

Values that are not hashable, that is, values containing lists, dictionaries or other mutable types (that are compared by value rather than by object identity) may not be used as keys.


The hash is used by dictionaries and sets to quickly look up the object. A good starting point is Wikipedia's article on hash tables.


I also looking for it from a very long time, Now I got my answer so shearing with you all...

Please use the Dictionary data type in python, its very very simile to the hash... Its also supported nested, simile to the to nested hash.

Example:-

dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
dict['Age'] = 8; # update existing entry
dict['School'] = "DPS School" # Add new entry

print ("dict['Age']: ", dict['Age'])
print ("dict['School']: ", dict['School'])

Dictionary data type:- https://www.tutorialspoint.com/python3/python_dictionary.htm

Hopes its solves the problem..

참고URL : https://stackoverflow.com/questions/17585730/what-does-hash-do-in-python

반응형