
On Jan 10, 2016, at 22:04, Terry Reedy <tjreedy@udel.edu> wrote:
On 1/10/2016 12:23 AM, Chris Angelico wrote:
(in reponse to Steven's response to my post)
There's more to it than that. Yes, a dict maps values to values; but the keys MUST be immutable
Keys just have to be hashable; only hashes need to be immutable.
By default, hashes depends on ids, which are immutable for a particular object within a run.
(otherwise hashing has problems),
only if the hash depends on values that mutate. Some do.
But if equality depends on values, the hash has to depend on those same values. (Because two values that are equal have to hash equal.) Which means that if equality depends on any mutable values, the type can't be hashable. Which is why none of the built-in mutable types are hashable. Of course Python doesn't stop you from writing your own types that can provide different hashes for equal values, or that can change hashes as they're mutated. It's even possible to use them as dict keys as long as you're very careful (the keys don't mutate in a way that changes either their hash or their equivalence while they're in the dict, and you never look up or add a key that's equal to an existing key but has a different hash). But it's not _that_ much of an oversimplification to say that keys have to be immutable. And any dict-based optimizations can safely rely on the same thing basic dict usage relies on: if the keys _aren't_ actually immutable, they're coded and used carefully (as described above) so that you can't tell they're mutable.