インターネットを検索してみましたが、ハッシュ可能の意味がわかりませんでした。
彼らがオブジェクトと言うとき、それはどういう意味ですかhashable
?hashable objects
インターネットを検索してみましたが、ハッシュ可能の意味がわかりませんでした。
彼らがオブジェクトと言うとき、それはどういう意味ですかhashable
?hashable objects
Python用語集から:
オブジェクトは、その存続期間中に変更されないハッシュ値(メソッドが必要)を持っている場合はハッシュ可能であり、他のオブジェクト(またはメソッド
__hash__()
が必要)と比較できます。等しいと比較するハッシュ可能なオブジェクトは、同じハッシュ値を持っている必要があります。__eq__()
__cmp__()
これらのデータ構造は内部でハッシュ値を使用するため、ハッシュ可能性により、オブジェクトはディクショナリキーおよびセットメンバーとして使用可能になります。
Pythonの不変の組み込みオブジェクトはすべてハッシュ可能ですが、変更可能なコンテナー(リストや辞書など)はハッシュ可能ではありません。ユーザー定義クラスのインスタンスであるオブジェクトは、デフォルトでハッシュ可能です。それらはすべて等しくなく比較され、それらのハッシュ値はそれら
id()
です。
ここでのすべての回答には、Pythonでのハッシュ可能なオブジェクトの適切な説明がありますが、最初にハッシュという用語を理解する必要があると思います。
ハッシュはコンピュータサイエンスの概念であり、大量のデータをすばやく保存してアクセスする、高性能の疑似ランダムアクセスデータ構造を作成するために使用されます。
たとえば、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
Pythonの用語集によると、ハッシュ可能なオブジェクトのインスタンスを作成すると、インスタンスのメンバーまたは値に従って変更できない値も計算されます。たとえば、その値は、次のように辞書のキーとして使用できます。
>>> 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
は同じメンバーであるため、同じであることがわかります。tuple_a
のキーとして使用するとdict_a
、の値が同じであることがわかります。つまりdict_a[tuple_c]
、辞書でキーとして使用すると、ハッシュ値が同じであるため、同じ値が返されます。ハッシュ可能ではないオブジェクトの場合、メソッド__hash__
は次のように定義されNone
ます。
>>> type(dict.__hash__)
<class 'NoneType'>
このハッシュ値は、動的な方法ではなく、インスタンスの初期化時に計算されると思います。そのため、不変オブジェクトのみがハッシュ可能です。お役に立てれば。
Hashable=ハッシュ可能。
さて、ハッシュとは何ですか?ハッシュ関数は、「Python」などの文字列などのオブジェクトを受け取り、固定サイズのコードを返す関数です。簡単にするために、戻り値が整数であると仮定します。
Python 3でhash('Python')を実行すると、結果として5952713340227947791が返されます。Pythonのバージョンが異なれば、基になるハッシュ関数を自由に変更できるため、異なる値を取得する可能性があります。重要なことは、hash('Python')を何度実行しても、同じバージョンのPythonで常に同じ結果が得られるということです。
ただし、hash('Java')は1753925553814008565を返します。したがって、ハッシュしているオブジェクトが変更されると、結果も変更されます。一方、ハッシュしているオブジェクトが変更されない場合、結果は同じままです。
なぜこれが重要なのですか?
たとえば、Python辞書では、キーが不変である必要があります。つまり、キーは変更されないオブジェクトである必要があります。他の基本型(int、float、bool)と同様に、文字列はPythonでは不変です。タプルとフリーズセットも不変です。一方、リストは変更できるため、不変ではありません(つまり、可変です)。同様に、dictは変更可能です。
したがって、何かがハッシュ可能であると言うとき、それは不変であることを意味します。可変型を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
Pythonでは、不変のオブジェクト(整数、ブール値、文字列、タプルなど)はハッシュ可能です。つまり、その値はその存続期間中に変更されません。これにより、Pythonは一意のハッシュ値を作成してそれを識別できます。これを辞書で使用して一意のキーを追跡し、セットを使用して一意の値を追跡できます。
これが、Pythonが辞書のキーに不変のデータ型を使用することを要求する理由です。
Pythonでは、インデックスを返すためにオブジェクトをセットのメンバーにすることができることを意味します。つまり、それらは一意のID/IDを持っています。
たとえば、Python3.3では次のようになります。
データ構造リストはハッシュ可能ではありませんが、データ構造タプルはハッシュ可能です。
Pythonでハッシュ可能なオブジェクトを理解するための実用的な例を紹介します。この例では2つのタプルを使用しています。タプルの各値には、その存続期間中に変更されることのない一意のハッシュ値があります。したがって、これに価値があることに基づいて、2つのタプル間の比較が行われます。Id()を使用して、タプル要素のハッシュ値を取得できます。
ハッシュテーブルを最初から作成するには、すべての値を「なし」に設定し、要件が発生したら変更する必要があります。ハッシュ可能なオブジェクトとは、変更可能なデータ型(辞書、リストなど)を指します。一方、セットは一度割り当てられると再初期化できないため、セットはハッシュできません。一方、set()のバリアントであるfrozenset()はハッシュ可能です。