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 で削除されました)。