2012-03-23 30 views
6

私はPython辞書のキーとしてカスタムオブジェクトを使用しています。これらのオブジェクトにはデフォルトのハッシュeqメソッドが定義されていますが、デフォルトの比較で使用されています しかし、これらのオブジェクトを比較するには、別の方法を使用する必要があります。 この特定の関数に対してのみ、これらのキー比較のために新しい比較演算子をオーバーライドするか、または渡す方法はありません。Python辞書キー(クラスオブジェクト)複数の比較関数との比較

更新日:私のクラスには、機能の種類を以下ました(私はハッシュ方法を編集することはできませんここでは、それは他の場所で多くの影響を与えます)

class test(object): 

    def __init__(self,name,city): 
     self.name=name 
     self.city=city 

    def __eq__(self,other): 
     hash_equality= (self.name==other.name) 
     if(not hash_equality): 
      #check with lower 
      return (self.name.lower()==other.name.lower()) 


    def __hash__(self): 
     return self.name.__hash__() 

my_dict={} 
a=test("a","city1") 
my_dict[a]="obj1" 
b=test("a","city2") 
print b in my_dict #prints true 
c=test("A","city1") 
print c in my_dict #prints false 
print c in my_dict.keys() #prints true 
# my_dict[c] throw error 

これは通常の機能です。しかし、ある特定の方法では、私は上書き/またはc in my_dictリターンが

またはmy_dict[c] will return "obj1"

ので、申し訳ありません

をTUREように、新しいハッシュコードが

def __hash__(self): 
    return self.name.lower().__hash__() 

のようなものです新しいカスタム比較子を渡したいです多くの更新。

ソートの場合と同様に、カスタムメソッドをcomparerとして渡すこともできます。ここで同じことを行う方法はありますか。

+0

私は質問を誤読しました(ソーティングに関するものだと思いました)。それでも、達成しようとしていることを説明するコードをいくつか用意してください。 –

+0

私は1つの関数だけで特定の比較メソッドを必要としています。ソート方法では、ソートではcompareerを渡すことができますが、キーをチェックしている間に行うことができます – gsagrawal

+0

ところで、 '__eq__'関数はハッシュを比較しますか?ハッシュには衝突が存在することがあるため、予期しない動作が発生することがあります。 –

答えて

0

のような奇妙な何かにつながります比較者に基づいて価値を与える。

0

オブジェクトに定義できるcomparison methodsを見てください。

あなたがやりたいことに応じて、__cmp__も面白いかもしれません。

+0

が質問の説明を更新しました。 __cmp__はここで役に立たない – gsagrawal

4

この作業を行う唯一の方法は、新しいハッシュと比較関数を使用して辞書のコピーを作成することです。その理由は、辞書があなたが望むようにルックアップを動作させるために、新しいハッシュ関数を使用して、保存されたすべてのキーを再ハッシュする必要があるからです。辞書にカスタムハッシュ関数を与えることはできません(常にキーオブジェクトの1つを使用します)。おそらく、カスタムハッシュ関数と比較関数を使用する型でオブジェクトをラップすることが最善の方法です。

class WrapKey(object): 
    __init__(self, wrapee): 
     self._wrapee = wrapee 

    __hash__(self): 
     return self._wrapee.name.lower().__hash__() 

    __eq__(self, other): 
     return self._wrapee.name == other._wrapee.name 


def func(d): 
    d_copy = dict((WrapKey(key), value) for key, value in d.iteritems()) 
    # d_copy will now ignore case 
0

このような状況のために少しハック:

class test(object): 

    def __init__(self,name,city,hash_func=None): 
     self.name=name 
     self.city=city 
     self.hash_func = hash_func 

    def __eq__(self,other): 
     return self.__hash__()==other.__hash__() 

    def __hash__(self): 
     if self.hash_func is None: 
      return self.name.__hash__() 
     else: 
      return self.hash_func(self) 

my_dict={} 
a=test("a","city1") 
my_dict[a]="obj1" 
b=test("a","city2") 
print b in my_dict #prints true 
c=test("A","city1") 
print c in my_dict #Prints false 
c.hash_func = lambda x: x.name.lower().__hash__() 
print c in my_dict #Now it prints true 

あなたは辞書に保存されているハッシュを変更することはできませんが、検索するためのハッシュの使用を変更することができます。もちろん、これは今私がパラメータとして比較子を取るカスタム辞書(辞書の派生クラス)を使用していると私はチェックする)のgetItemsを(含まれてい上書きしている。この

my_dict={} 
a=test("a","city1") 
my_dict[a]="obj1" 
a.hash_func = lambda x: 1 
for key in my_dict: 
    print key in my_dict # False 
0

手順:カスタムキークラスを実装し、ハッシュおよび等価関数をオーバーライドします。

class CustomDictKey(object): 

def __init__(self, 
      param1, 
      param2): 

      self._param1 = param1 
      self._param2 = param2 

# overriding hash and equality function does the trick 

def __hash__(self): 
    return hash((self._param1, 
      self._param2)) 

def __eq__(self, other): 
    return ((self._param1, 
      self._param2) == (other._param1, 
      other._param2)) 

def __str__(self): 
    return "param 1: {0} param 2: {1} ".format(self._param1, self._param2) 

mainメソッド
if name == 'main': 

    # create custom key 
    k1 = CustomDictKey(10,5) 

    k2 = CustomDictKey (2, 4) 

    dictionary = {} 

    #insert elements in dictionary with custom key 
    dictionary[k1] = 10 
    dictionary[k2] = 20 

    # access dictionary values with custom keys and print values 
    print "key: ", k1, "val :", dictionary[k1] 
    print "key: ", k2, "val :", dictionary[k2] 

は、完全な詳細については、リンク Using custom class as key in Python dictionaryを参照してください。