概要
Python
のhash
関数は、オブジェクトに対してハッシュ値(整数)を返すための組み込み関数です。このハッシュ値は、ハッシュテーブルなどのデータ構造で効率的なデータ検索や格納を可能にするために使用されます。例えば、Python
のdict
(辞書)やset
(集合)では、このハッシュ値を使ってオブジェクトをキーとして扱うことができます。
構文
hash(オブジェクト)
パラメータ
- オブジェクト
ハッシュ値を取得したい対象のオブジェクト。イミュータブル(変更不可)なオブジェクトのみが対応しています。
戻り値
指定したオブジェクトのハッシュ値を整数として返します。ハッシュ値はオブジェクトの内容を元に計算され、同じオブジェクトには常に同じハッシュ値が返されます。
使用例
整数、文字列、タプルのハッシュ値取得
以下の例では、hash
関数を使って整数、文字列、タプルのハッシュ値を取得しています。
# 整数のハッシュ
print(hash(42)) # 例: 42
# 文字列のハッシュ
print(hash("Hello, World!")) # 例: 4397119838469387859
# タプルのハッシュ
print(hash((1, 2, 3))) # 例: 529344067295497451
これらの例では、イミュータブルなオブジェクト(整数、文字列、タプル)に対してハッシュ値が返されています。hash
関数は、これらのオブジェクトが辞書や集合のキーとして使用される際の基盤となります。
ミュータブルなオブジェクトはハッシュ化できない
一方、リストや辞書のように変更可能なオブジェクトに対してはhash
関数を使うことができません。もし試みると、TypeError
が発生します。
# リストのハッシュ化はエラーになる
my_list = [1, 2, 3]
print(hash(my_list)) # TypeError: unhashable type: 'list'
リストはミュータブル(変更可能)であるため、ハッシュ化できません。ハッシュ化されるためにはオブジェクトが変更不可である必要があります。
ハッシュの用途
辞書のキーや集合の要素
Python
のdict
やset
はハッシュテーブルを利用してデータを管理しています。そのため、これらのデータ構造のキーや要素として使用されるオブジェクトは、ハッシュ可能である必要があります。例えば、次のようにハッシュ化可能なオブジェクト(文字列やタプル)をキーとして使用できます。
# 辞書のキーとしての使用例
my_dict = {("apple", "banana"): "fruits", "age": 25}
print(my_dict[("apple", "banana")]) # 出力: fruits
この例では、タプル("apple", "banana")
が辞書のキーとして正常に使用されており、その内部ではハッシュ値を元にデータの検索が行われています。
オブジェクトの同一性比較
ハッシュ値はオブジェクトの同一性を判定するためにも使われます。ハッシュ値が異なるオブジェクトは内容も異なり、同じハッシュ値を持つオブジェクトは内容が同じ可能性が高いです(ただし、ハッシュの衝突が発生する可能性もあります)。次の例は、同じ内容を持つオブジェクトが同じハッシュ値を持つかを確認します。
a = "`Python`"
b = "`Python`"
# 同じ内容のオブジェクトは同じハッシュ値を持つ
print(hash(a)) # 例: -1450640930555811045
print(hash(b)) # 同じ: -1450640930555811045
この例では、文字列a
とb
は同じ内容を持つため、同じハッシュ値が返されています。
注意点
ハッシュ値は実行ごとに変わる場合がある
Python
3.xでは、セキュリティのため、異なる実行セッション間で同じオブジェクトに対するハッシュ値が異なる場合があります。これは、ハッシュを使った攻撃を防ぐために実行ごとに異なるランダムシードが使用されるためです。同じプログラム実行中では同じハッシュ値が返されますが、別のセッションでは異なる可能性があります。
カスタムオブジェクトのハッシュ化
カスタムクラスを作成した際、そのオブジェクトを辞書のキーとして使いたい場合は、__hash__
メソッドを実装する必要があります。デフォルトでは、クラスインスタンスはハッシュ可能ですが、独自のハッシュ計算を定義することも可能です。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __hash__(self):
return hash((self.x, self.y))
p = Point(1, 2)
print(hash(p)) # タプル (1, 2) のハッシュ値が返される
この例では、Point
クラスに対して__hash__
メソッドを実装し、オブジェクトのx
とy
座標のタプルをハッシュ値として返しています。
まとめ
Python
のhash
関数は、オブジェクトのハッシュ値を取得し、辞書や集合のようなハッシュテーブルを基盤とするデータ構造において効率的なデータ操作を可能にします。イミュータブルなオブジェクトに対して使われ、動的なデータの同一性やハッシュテーブルに基づく検索を最適化する役割を果たします。カスタムクラスの場合は、必要に応じて__hash__
メソッドを実装することで、独自のハッシュ値を定義することも可能です。