Is there a Python container that acts like a dictionary but doesn't need both key and value?

Question:

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.

Asked By: Alexander Soare

||

Answers:

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).

Answered By: Eureka
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.