Suppose I have a set which contains objects.
class C(object):
def __init__(self, value):
self.value = value
def __repr__(self):
return 'C({}):{}'.format(self.value, id(self))
def __eq__(self, other):
return self.value == other.value
def __hash__(self):
return hash(self.value)
cset = {C(1), C(2)}
print 'cset:', cset
cset: set([C(1):140241436167120, C(2):140241436167184])
I want to find an object in the set, and get a reference to the object.
c1 = C(1)
print 'c1:', c1
found, = cset & {c1}
print 'way1 found:', found
found, = {c1} & cset
print 'way2 found:', found
c1: C(1):140241436167248
way1 found: C(1):140241436167248
way2 found: C(1):140241436167248
Those ways are no good; return the reference to c1 (id=140241436167248), not to the object (id=140241436167120) in the set.
Just to show what I want, quick and dirty way is like this.
found, = [x for x in cset if x == c1]
print 'way3 found:', found
way3 found: C(1):140241436167120
This way returns what I wanted, the reference to the object (id=140241436167120) in the set. But it is using linear search. Is there any better way?
The problem is that you're trying to use your set
like a mapping. That's not going to work very well...
Instead, don't make your objects explicitly hashible. If you have a uniqueness constraint, use a dictionary to map the values to instances rather than a set. A dictionary can enforce uniqueness just as easily as a set
and it provides the mapping behavior that you desire.
if c1.value in cdict:
c1 = cdict[c1.value] # Trade in the `c1` we have for one already in `cdict`
Additionally, using a dict
is less "clever" which is almost always a win from a readability standpoint.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.