簡體   English   中英

Python字典鍵(它是類對象)與多個比較器進行比較

[英]Python dictionary keys(which are class objects) comparison with multiple comparer

我在python字典中使用自定義對象作為鍵。 這些對象定義了一些默認的hasheq方法,這些方法在默認比較中使用但是在某些函數中我需要使用不同的方法來比較這些對象。 那么有沒有辦法為這個特定的函數覆蓋或傳遞一個新的比較器來進行這些鍵比較。

更新:我的類有以下類型的功能(這里我不能編輯哈希方法,它會在其他地方影響很多)

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

這是正常的功能。 但是在一個特定的方法中,我想覆蓋/或傳遞一個新的自定義比較器,其中新的哈希代碼就像

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

以便c in my_dict中的c in my_dict返回ture

my_dict[c] will return "obj1"

很抱歉這么多的更新。

像在排序中我們可以將自定義方法作為比較器傳遞,有沒有辦法在這里做同樣的事情。

使這項工作的唯一方法是使用新的哈希和比較函數創建字典的副本。 原因是字典需要使用新的哈希函數重新散列每個存儲的密鑰,以使查找按照您的意願工作。 由於您無法為字典提供自定義哈希函數(它總是使用其中一個鍵對象),因此最好的辦法是將對象包裝在使用自定義哈希和比較函數的類型中。

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

步驟:實現自定義鍵類並覆蓋哈希和相等函數。

例如

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)

主要方法

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]

有關完整的詳細信息,請參閱鏈接使用自定義類作為Python字典中的鍵

看看您可以在對象中定義的比較方法

根據你想做的事情, __cmp__也可能很有趣。

這種情況有點破解:

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

您無法更改存儲在dict中的哈希值,但您可以更改哈希用於查找。 當然,這會導致像這樣的奇怪

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

現在我使用自定義dict(派生類的dict),它將comparer作為參數,我已經覆蓋了containsgetitems (),它根據比較器檢查和給出值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM