Pythonにおける「ハッシュ可能」とは?
Pythonでは、オブジェクトが「ハッシュ可能」であるとは、ハッシュ値を持ち、ハッシュ値が不変であることを意味します。これは、オブジェクトが辞書のキーやセットの要素として使用できることを示しています。一般に、イミュータブル(不変)なオブジェクトはハッシュ可能であり、ミュータブル(可変)なオブジェクトはハッシュ可能ではありません。
ハッシュ可能なオブジェクトの特徴
ハッシュ可能なオブジェクトは以下の特徴を持ちます:
- 不変であること(例: タプル、文字列、整数)
- __hash__() メソッドを持ち、ハッシュ値を返すこと
- __eq__() メソッドを持ち、オブジェクトの等価性を比較できること
ハッシュ可能なオブジェクトの例
以下に、Pythonでハッシュ可能なオブジェクトの例を示します。
# ハッシュ可能なオブジェクトの例 hashable_tuple = (1, 2, 3) hashable_string = "hello" hashable_int = 42 print(hash(hashable_tuple)) # タプルのハッシュ値 print(hash(hashable_string)) # 文字列のハッシュ値 print(hash(hashable_int)) # 整数のハッシュ値
出力例:
529344067295497451 -691614558913186973 42
ハッシュ可能でないオブジェクトの例
リストや辞書のようなミュータブルなオブジェクトはハッシュ可能ではありません。以下に例を示します。
# ハッシュ可能でないオブジェクトの例 unhashable_list = [1, 2, 3] unhashable_dict = {"key": "value"} # これらのオブジェクトはハッシュ可能ではないため、エラーが発生します # print(hash(unhashable_list)) # print(hash(unhashable_dict))
上記のコードを実行すると、TypeErrorが発生します。
カスタムオブジェクトをハッシュ可能にする方法
自分のクラスをハッシュ可能にしたい場合、__hash__() メソッドと __eq__() メソッドを実装する必要があります。以下にその例を示します。
class HashablePoint: def __init__(self, x, y): self.x = x self.y = y def __eq__(self, other): if isinstance(other, HashablePoint): return self.x == other.x and self.y == other.y return False def __hash__(self): return hash((self.x, self.y)) point1 = HashablePoint(1, 2) point2 = HashablePoint(1, 2) print(hash(point1)) # カスタムオブジェクトのハッシュ値 print(point1 == point2) # 等価性のチェック
出力例:
-3550055125485641917 True
まとめ
Pythonにおけるハッシュ可能性は、データ構造の効率的な操作に不可欠です。オブジェクトがハッシュ可能であることで、辞書のキーやセットの要素として使用できます。イミュータブルなオブジェクトは通常ハッシュ可能であり、自作のクラスをハッシュ可能にするためには、適切なメソッドを実装する必要があります。
Python 3における”hashable”とは、ハッシュ関数によって一意の値が生成されるオブジェクトを指します。つまり、そのオブジェクトは辞書のキーとして使用できることを意味します。Pythonのデータ型の中で、不変のオブジェクト(例:整数、文字列、タプル)はハッシュ可能であり、変更可能なオブジェクト(例:リスト、辞書、集合)はハッシュ不可能です。ハッシュ可能なオブジェクトは、辞書や集合などのデータ構造で効率的に利用される重要な概念です。