Reputation: 18745
How could I make set
to have objects equality depended on a custom attribute which I'd set? Like Java's equals
method.
The point is that I want to have a set which contains tuples (x,y)
. When I try to put (x,y)
tuple into the set, the result would depends on x
.
set.add((x,y))
- OK
set.add((x,z))
- Can't add because there is already a touple which has x as a first value.
Upvotes: 2
Views: 703
Reputation: 21942
Why not use a dict
instead of a set
of tuple
s:
d = {}
d[x] = y
d[x] = z
This will override the value y
with z
though, but it makes sure you only have one value at a time.
If you don't want the overriding to be possible, you can subclass dict
to prevent it:
class HalfFrozenDict(dict): # Name is a subject to change
def __setitem__(self, key, value):
if key in self:
raise KeyError("Key '{}' already exists!".format(key))
super().__setitem__(key, value)
def update(self, other):
other = {key: other[key] for key in other if key not in self}
super().update(other)
Currently it raises an error if you try to re-set an item:
>>> d = HalfFrozenDict()
>>> d[0] = 1
>>> d[0] = 2
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
d[0] = 2
File "<pyshell#1>", line 5, in __setitem__
raise KeyError("Key: '{}' already exists!".format(key))
KeyError: "Key '0' already exists!"
Also, calling d.update(other)
will just ignore the duplicate keys from the other
dict.
Both of these behaviours are a subject to change: would you rather raise an error on "invalid" update()
call? Would you prefer to ignore a re-setting of an item (I think error is better in this case)?
Upvotes: 2