Reputation: 185
I have a dict where the keys are of a class type. The __eq__
method of this class is implemented such that some of the class elements are ignored during comparison:
class ID:
def __init__(self, name, location):
self.name = name
self.location = location
def __eq__(self, other):
return self.name == other.name
def __hash__(self):
return hash(self.name)
I use the dict to find elements of this class, no matter what the value of the location
element is:
types = {ID("foo", "<stdin>:2:5"): "some data", ID("bar", "<stdin>:10:5"): "other data"}
search = ID("foo", "<stdin>:11:5")
if search in types:
print(f"duplicate entry {search.name}")
However, when I want the location
value of the key stored in the dict, I need to iterate through the dict:
if search in types:
print(f"duplicate entry {search.name}")
r = [k for k, _ in types.items() if k == search][0]
print(f"previous location: {r.location}")
Is there any better way to obtain the key object of a dict from another key (which is considered equal)?
Edit: I'm interested in Python 3 only.
Upvotes: 1
Views: 125
Reputation: 28663
You can create a dict sub class that will find the duplicate key for you
class ID:
def __init__(self, name, location):
self.name = name
self.location = location
def __eq__(self, other):
return self.name == other.name
def __hash__(self):
return hash(self.name)
class MyDict(dict):
def getSimilarKey(self, key):
for k in self.keys():
if k == key:
return k
return None
@classmethod
def create(cls, d):
tmp = cls()
tmp.update(d)
return tmp
types = MyDict.create({ID("foo", "<stdin>:2:5"): "some data", ID("bar", "<stdin>:10:5"): "other data"})
search = ID("foo", "<stdin>:11:5")
if search in types:
print(f"duplicate entry {search.name}")
print(f"previous location: {types.getSimilarKey(search).location}")
Upvotes: 0
Reputation: 1313
Have you tried to directly get the attribute with this piece of code ?
search.location
or
types[search].location
This will give you the value you are looking for.
Upvotes: 0
Reputation: 61910
You could store the key object as part of the values:
# store the value and key as a tuple
lookup_types = {k: (k, v) for k, v in types.items()}
if search in lookup_types:
print(f"duplicate entry {search.name}")
r, _ = lookup_types[search]
print(f"previous location: {r.location}")
Output
duplicate entry foo
previous location: <stdin>:2:5
Upvotes: 2