2009-08-04 19 views
1

Iはint S、float S、キーとしてstring sのdictのインスタンスを持っているが、問題が存在する場合であるafloatをとしてintなどとb 、およびfloat(a) == b、それらのハッシュ値は同じで、対応する値を取得するためにこのケースに一意のハッシュ値が必要なため、取得したくないものです。問題:ハッシュ(1)==ハッシュ(1.0)

例:私は必要なもの

d = {1:'1', 1.0:'1.0', '1':1, '1.0':1.0} 
d[1] == '1.0' 
d[1.0] == '1.0' 
d['1'] == 1 
d['1.0'] == 1.0 

は次のとおりです。

d = {1:'1', 1.0:'1.0', '1':1, '1.0':1.0} 
d[1] == '1' 
d[1.0] == '1.0' 
d['1'] == 1 
d['1.0'] == 1.0 
+2

。 1。0 == 1 –

答えて

7

1 == 1.0以降、hash(1) != hash(1.0)の場合は、ハッシュのセマンティクスがひどく壊れてしまいます(したがって、ディクテーションとセット)。より一般的には、x == yがすべてxyのためにhash(x) == hash(y)を含意する場合が常にある必要があります(もちろん、逆の意味を保持する必要はありません)。

したがって、dict dには3つのエントリしかありません.Dictディスプレイに書いた2番目のエントリは最初のものを上書きします。あなたも(他の他のメソッドをオーバーライドすることができますあなたの正確なニーズに応じ

class W(object): 

    def __init__(self, x): 
    self.x = x 
    self.t = type(x) 

    def __eq__(self, other): 
    t = type(other) 
    if t != type(self): 
     return False 
    return self.x == other.x and self.t == other.t 

    def __hash__(self): 
    return hash(self.x)^hash(self.t) 

    def __getattr__(self, name): 
    return getattr(self.x, name) 

:あなたは(より一般的に数字ではなく)のみの同一の型の間で保持するための平等を強制する必要がある場合は、次のようなラッパーを必要とします__cmp__または__le__などの比較方法、算術演算、__repr__など)。いずれにしても、必要なものと同様の辞書を作成することができます。裸の1.0の代わりに1W(1.0)の代わりにW(1)というキーを使用してください(数字以外はラップする必要はありません。そうすることを選択し、すべてのキーが均等にラップされている場合は、あなたの辞書からの検索を容易にすることができます)。

+0

ラッピングオブジェクトは解決策と見なすことができ、私が必要とするものに本当に近いです。とにかく、私は次のことについて不思議に思っています:h = hash( 'a'); d = {'a':1、h:2};結果はd ['a']!= d [h]です。なぜなら、キーのハッシュ値は同じですが、型の違いは同じではないので、dictメソッドgetitemはキーのハッシュ値とキーの型の両方をチェックします。もしそうなら、intとfloatで同じ結果が得られないのはなぜですか? – mtasic85

+0

@mtasic、なぜあなたは '1 == 1.0'なのか、なぜ' dict'が他の方法で平等をチェックするのではなく '=='を使っているのか、 '5.0 * x == 5.0 * y'なら、算術と代数の最も基本的な期待を破ることなく、どのように' x!= y'にすることができるのでしょうか?後者の場合、 'x == y'でも' d [x]!= d [y] 'なら' dict'はどのようにマッピングできますか?これらは強く、貴重で、平等、算術、および索引付けの不変の不変特性であり、タイプフェティシズムはそれらを粉砕する正当な理由ではない。平等は常に哲学的問題ですが、... –

1

これはあなたの問題を解決していませんが、Python 2.6's number documentationから:

実装者が等しくなるように注意する必要があります同じ数値にハッシュします。

浮動小数点1.00001などで作成できますか?

6

辞書キーとしての浮動小数点数を「賢明でない」とすると、2つの浮動小数点数が同じ値になることを保証することはできません。

キーは、所定の小数点以下の桁数にキーを掛け、その整数をキーとして使用することをお勧めします。

編集:実際の数字キーを使用して辞書を望んでいないようですが、単に入力の種類に基づいて出力をフォーマットしたいのですか?

+0

良い点ですが、__setitem__、__getitem__、__delitem__の各メソッドで必要な場合には、すべての重要な型と他のすべての型の分離されたdictsで新しいクラスを作成できることも知っています。キーと値を格納するために使用する辞書を決定します。 – mtasic85

2

あなたが本当に同じように、おそらくハック何かを、違いを知っておく必要がある場合:あなたはこれを行うことはできません

x = '1' 
y = 1 

hash(type(x) + x) != hash(type(y) + y) 
関連する問題