(hash(key1) == hash(key2)) and (key1 == key2)ハッシュによる高速化を実現しつつ、万が一(兆が一?)のハッシュの衝突に備え、== 演算子も併用しています。
== 演算子が併用されることで、仮にハッシュの衝突が起こったとしても、問題とならない場合が多いです。
>>> hash('W') # ある環境での文字列'W' のハッシュ値
332122003784942950
>>> hash(332122003784942950) # 同じハッシュ値を持つ整数型
332122003784942950
# 'W' と 332122003784942950 を key とする dict でも
# == 演算子のおかげで別々の key となる
>>> d = {'W': None, 332122003784942950: None}
>>> d
{'W': None, 332122003784942950: None}
他方で、意外にあっさりと困るパターンも見つかります。int, float, bool, complex はハッシュ値の計算、および ==演算子に共通性があるためです。
>>> hash(1) # 整数 1 のハッシュ値は 1
1
>>> hash(1.0) # 浮動小数 1.0 のハッシュ値は 1
1
>>> hash(True) # 論理型 True のハッシュ値は 1
1
>>> hash(1 + 0j) # 複素数 1 + 0j のハッシュ値は 1
1
>>> 1 == 1.0 == True == 1 + 0j # 1 と 1.0 と True と 1 + 0j は同値
True
# 1 と 1.0 と True と 1 + 0j を key とする dict を作成すると、
# 重複 key と判定され、1つの key になる
>>> d = {1: None, 1.0: None, True: None, 1 + 0j: None}
>>> d
{1: None}
結論として、dict の key にあまり色々な型を混ぜるのは得策ではありません。可能なら、文字列型と整数型(およびそれを tuple で組み合わせたもの)だけにするのが良いでしょう。
0 件のコメント:
コメントを投稿