7

コンソールで入力しました

>>> class S(str): pass
...
>>> a = 'hello'
>>> b = S('hello')
>>> d = {a:a, b:b}
>>> d
{'hello': 'hello'}
>>> type(d[a])
<class '__main__.S'>
>>> type(d[b])
<class '__main__.S'>

最初は、dペアを1つだけ保持した理由は、同じ値hash(a)hash(b)返したためだと思ったので、次のことを試しました。

>>> class A(object):
...     def __hash__(self):
...             return 0
... 
>>> class B(object):
...     def __hash__(self):
...             return 0
... 
>>> d = {A():A(),B():B()}
>>> d
{<__main__.A object at 0x101808b90>: <__main__.A object at 0x101808b10>, <__main__.B object at 0x101808d10>: <__main__.B object at 0x101808cd0>}

今、私は混乱しています。最初のコードリストでは、d1つのペアしか保持されていませんが、2番目のリストでは、d同じハッシュを使用しているにもかかわらず、両方のキーが保持されているのはなぜですか?

4

4 に答える 4

8

元の例の2つのオブジェクトは、ハッシュが同じであるためではなく、比較が等しいために折りたたまれています。ディクトキーは、ハッシュではなく、同等性に関して一意です。Pythonでは、等しいと比較する2つのオブジェクトが同じハッシュを持っている必要があります(ただし、必ずしもその逆である必要はありません)。

最初の例では、2つのオブジェクトはどちらもstr同等の動作をしているため、同等です。2つのオブジェクトは同等に比較されるため、1つに折りたたまれます。2番目の例では、それらは等しく比較されません。デフォルトでは、ユーザー定義クラスは同等性のためにIDを使用します。つまり、各オブジェクトはそれ自体と同等にのみ比較されます。したがって、2つのオブジェクトは等しくありません。それらが同じハッシュを持っているかどうかは問題ではありません。

于 2012-12-21T05:01:00.907 に答える
4

ハッシュは、辞書内の一意のキーを決定しません。ある意味で、ハッシュ関数は、辞書がそのエントリを内部的に格納する方法を決定するという点で、「実装の詳細」です。a == bはhash(a)== hash(b)を意味しますが、その逆は一般的には成り立ちません。辞書で同等のキーとして扱われるためには、2つのキーも互いに等しくなければなりません(==演算子を適用する場合)。

于 2012-12-21T05:01:54.330 に答える
2

タイプをハッシュ可能する場合は、も定義する必要があります__eq__()。正しくstr定義しますが、しません。__eq__()AB

于 2012-12-21T04:59:40.433 に答える
0

キーは、1番目と2番目のオブジェクトで異なります。それらはオブジェクトであるため、キーは文字列ではなくオブジェクトと同等の読み取り可能なものです。

于 2012-12-21T05:01:18.503 に答える