setオブジェクトの同一性の管理(Python)
setオブジェクトの同一性の管理(Python)
Pythonのset、集合型を用いてPerson.nameを基準にしたオブジェクトの同一性の管理を行いたくて、__hash__を実装したけど躓いた。__eq__メソッドの実装を忘れており、Python のデフォルトの __eq__ が使用されていたのが原因 code:py
def to_dict(obj):
return {k: v for k, v in vars(obj).items() if not k.startswith("_")}
class Person:
def __init__(self, name, answer) -> None:
self.name = name
self.answer = answer
def __hash__(self) -> int:
return hash(self.name)
def __eq__(self, other) -> bool:
if not isinstance(other, Person):
return NotImplemented
return self.name == other.name
def __repr__(self):
params = ", ".join(f"{k}={v!r}" for k, v in to_dict(self).items())
return f"{self.__class__.__name__}({params})"
people = [
Person("Taro", 42),
Person("Jiro", 42),
Person("Jiro", 41),
]
for person in set(people):
person_spec = {
"name": person.name,
"hash": hash(person),
"id": id(person),
}
print(person_spec)
# {'name': 'Taro', 'hash': -8487701407697596247, 'id': 272172045400064}
# {'name': 'Jiro', 'hash': -3058694779974787363, 'id': 272172045400016}
ハッシュテーブルにおける要素の重複チェック
ハッシュ値の比較→等価比較
ハッシュ値が異なる場合は別の要素とみなす
ハッシュ値が同じ場合に、__eq__メソッドで実際にオブジェクトが等価かどうかを比較する