Say I have:
@dataclass
class Foo:
foo_id: int
# Other interesting fields.
def __hash__(self):
return self.foo_id.__hash__()
And I make a foos_set = {Foo(i) for i in range(10)}. I had always assumed that set.remove used the hash for constant-time lookup. So I thought it would be reasonable to think that foos_set.remove(6) should work. But actually, it raises a KeyError. You’d need to do foo_set.remove(Foo(6)). In fact, if there are more fields, you need to make sure that all of them match!
I suppose the right thing for me to do is just make a foos_dict = {i: Foo(i) for i in range(10)}. And I’d be happy to do that, but it just feels unnecessarily clunky so here I am asking if there’s another container I don’t know about.
>Solution :
If you want to be able to jump to and delete a particular entry based on an id, use a dictionary
A dictionary is par excellence a container that is indexed by a specific piece of information – the key.
A set is, in effect, indexed on the whole entry, not just the key. A list is indexed on something that is not part of the entry itself, but rather its position in the list.
So
foos_dict = {i: Foo(i) for i in range(10)}
is in fact the perfect way to achieve what you want.
This proves that you need a dictionary!
You are literally describing a dictionary:
I wanted to also be able to retrieve an element from the set using just the ID (without having to do a search).