Why iterators and generators are hashable?


As title. I mean, you can invoke next(obj) and point to the next element. So the internal state of the iterable or generator will change.

Why they are hashable?

Asked By: Marco Sulla



While the internal state of the generator can change, the generator as a whole can never add something to itself, and can never go back a step while iterating over it. Therefore, a generator is a fixed immutable object, which is almost the definition of being hashable.

But even more deeply than that, even mutable objects can be hashable as long as they define __hash__ as an instance method, but that is rarely desireable for mutable objects.

Answered By: Ofer Sadan

The general rule for hashing objects is:

  1. Unless __eq__ is overridden, object equality is defined by identity, and hashing matches
  2. If __eq__ is overridden, and __hash__ is not, then hashing is blocked by default (because mutability that affects the result of an equality check would break the hash invariants); re-enabling hashing requires implementing __hash__, which implicitly says "My equality and hash semantics are stable/consistent over time", but doesn’t require that things not tied to equality or the hash code be stable.

Point is, the condition for hashability isn’t full immutability, it’s consistency with equality (and implied stability of both equality and hash). Since most iterators and all generators don’t implement __eq__ (there is no meaningful way to implement it without running out the iterator and losing the information you just used to compare it), it’s all based on identity, just like with any user-defined object that doesn’t define equality.

Answered By: ShadowRanger
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.