Pythondict
実装では、ハッシュ値を使用して、キーに基づいて値をまばらに保存し、そのストレージでの衝突を回避します。の結果をhash()
起点とするものであり、確定的な位置付けではありません。
したがって、 がhash(4)
返されますが、基礎となる C 構造体の正確な「位置」は、すでにそこにある他のキーと、現在のテーブルの大き4
さにも基づいています。たとえば、python ハッシュ テーブルは必要に応じてサイズ変更されます (項目が追加されます)。
dict には順序がないため、これについて心配する必要はなく、影響を与えることもできません。dict で順序付けする必要がある場合は、collections.OrderedDict()
代わりに実装を使用してください。これにより、順序付けが個別に追跡されます。
Python ハッシュ テーブルの実装の詳細
ウィキペディアでハッシュ テーブルがどのように機能するかを読みたいと思うかもしれません。Python は、その実装にオープン アドレッシングを使用します。
テーブル内のスロットを選択すると、ハッシュ値 (整数) のモジュラスと現在のテーブル サイズが取得されるため、サイズ 32 のテーブルでは、キー45
、ハッシュ値45
は最初にスロット 14 に格納されます。
衝突が発生した場合 (スロット 14 に別のものが格納されており45
、それは integer ではありません)、スロットの値は、空のスロットが見つかるか、代わりに同じキーが見つかるまで摂動されます。摂動は次の式で行われます。
perturb = slot = hash
while slot_is_full and item_in_slot_is_not_equal_to_key:
slot = (5*slot) + 1 + perturb
perturb >>= 5
そのため、衝突が発生すると、テーブル全体をスキャンするまで、別のスロットが段階的に小さいステップで選択されます。必要に応じて、テーブルのサイズが既に変更されてスペースが確保されていることに注意してください。
これが正しく機能するためには、カスタム タイプに__hash__()
メソッドと実装の両方が必要であり__eq__()
、2 つのインスタンスが同じキーを表しているかどうかを判断する必要があります。ハッシュ値を一致させるだけでは不十分です。2 つのインスタンスがまったく同じキーを表しているdict
と実装が見なすには、両方のハッシュ値が一致し、==
等値演算子に対して True を返す必要があります。このようなオブジェクトはhashableと見なされます。
(Python 2.x の場合、 を実装する代わりに__cmp__()
フック__eq__()
を実装します。このサポートは Python 3 で削除されました)。