简体   繁体   中英

How to get a reference to an object in Python set

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM