Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am using custom objects as keys in python dictionary. 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. 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

or 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.

like image 709
gsagrawal Avatar asked Mar 23 '12 07:03

gsagrawal


People also ask

What is the Python function that compares items of two dictionaries?

The compare method cmp() is used in Python to compare values and keys of two dictionaries. If method returns 0 if both dictionaries are equal, 1 if dic1 > dict2 and -1 if dict1 < dict2.

Can a dictionary have multiple values for the same key?

In python, if we want a dictionary in which one key has multiple values, then we need to associate an object with each key as value. This value object should be capable of having various values inside it. We can either use a tuple or a list as a value in the dictionary to associate multiple values with a key.

How do you check if two dictionaries have the same keys and values?

Check if two nested dictionaries are equal in Python To do this task, we are going to use the == operator and this method will help the user to check whether the two given dictionaries are equal or not.


1 Answers

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
like image 94
Björn Pollex Avatar answered Oct 27 '22 21:10

Björn Pollex