[英]Python dictionary keys(which are class objects) comparison with multiple comparer
I am using custom objects as keys in python dictionary. 我在python字典中使用自定义对象作为键。 These objects has some default hash and eq methods defined which are being used in default comparison But in some function i need to use a different way to compare these objects.
这些对象定义了一些默认的hash和eq方法,这些方法在默认比较中使用但是在某些函数中我需要使用不同的方法来比较这些对象。 So is there any way to override or pass a new comparer for these key comparison for this specific function only.
那么有没有办法为这个特定的函数覆盖或传递一个新的比较器来进行这些键比较。
Updated: My class has following type of functionality ( here i can not edit hash method ,it will affect a lot at other places) 更新:我的类有以下类型的功能(这里我不能编辑哈希方法,它会在其他地方影响很多)
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
This is the normal functionality. 这是正常的功能。 But in one specific method i want to override/or pass a new custom comparer where the new hash code is like
但是在一个特定的方法中,我想覆盖/或传递一个新的自定义比较器,其中新的哈希代码就像
def __hash__(self):
return self.name.lower().__hash__()
so that c in my_dict
returns ture 以便
c in my_dict
中的c in my_dict
返回ture
or my_dict[c] will return "obj1"
或
my_dict[c] will return "obj1"
Sorry for so many updates. 很抱歉这么多的更新。
Like in sorting we can pass custom method as comparer , is there any way to do the same here. 像在排序中我们可以将自定义方法作为比较器传递,有没有办法在这里做同样的事情。
The only way to make this work is to create a copy of your dictionary using the new hash and comparison-function. 使这项工作的唯一方法是使用新的哈希和比较函数创建字典的副本。 The reason is that the dictionary needs to rehash every stored key with the new hash-function to make the lookup work as you desire.
原因是字典需要使用新的哈希函数重新散列每个存储的密钥,以使查找按照您的意愿工作。 Since you cannot provide a custom hash-function to a dictionary (it always uses the one of the key-objects), your best bet is probably to wrap your objects in a type that uses your custom hash and comparison-functions.
由于您无法为字典提供自定义哈希函数(它总是使用其中一个键对象),因此最好的办法是将对象包装在使用自定义哈希和比较函数的类型中。
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
Steps : Implement a custom key class and override hash and equality function. 步骤:实现自定义键类并覆盖哈希和相等函数。
eg 例如
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]
Refer the link Using custom class as key in Python dictionary for complete details. 有关完整的详细信息,请参阅链接使用自定义类作为Python字典中的键 。
Have a look at the comparison methods you can define in an object. 看看您可以在对象中定义的比较方法 。
Depending on what you want to do, __cmp__
might also be interesting. 根据你想做的事情,
__cmp__
也可能很有趣。
A little hack for this situation: 这种情况有点破解:
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
You can't change the hash stored in the dict, but you can change the hash use for looking up. 您无法更改存储在dict中的哈希值,但您可以更改哈希用于查找。 Of course, this leads to something weird like this
当然,这会导致像这样的奇怪
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作为参数,我已经覆盖了contains和getitems (),它根据比较器检查和给出值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.